Introduction
Object pooling is a common programming pattern used in game development to efficiently manage and reuse game objects.
Object pooling involves creating and maintaining a pool (or a collection) of pre-instantiated objects that can be reused instead of instantiating and destroying objects dynamically during runtime. This is particularly useful in scenarios where the creation and destruction of objects are frequent, such as in games with a large number of bullets, enemies, or other entities.
A basic overview of how object pooling works:
Initialization: Instantiate a certain number of objects at the start of the game (deactivated and added to a pool) or when they are needed for the first time.
Usage: Instead of creating new objects when needed, objects from the pool are activated and reused. This is typically done by enabling and positioning them as needed.
Deactivation: When an object is no longer needed, it is deactivated and returned to the pool for future use, rather than being destroyed.
Object pooling can help improve performance by reducing the overhead associated with dynamic instantiation and destruction of objects during gameplay.
Performance
Efficiency is a high goal in optimizing your game, aiming for peak speed and smooth performance. This entails addressing potential issues like negative spikes in frames per second and minimizing unnecessary memory allocation. To optimize garbage collection and to ensure a seamless and resource-efficient gaming experience.
Frames Per Seconds
The following image shows the average minimum frames per second (fps) over time with and without pooling.
Figure 1 - Line-Graph: Average minimum frames per second (fps) over time with and without pooling.
On the X-Axis you see the time (20 ~ 1 second). On the Y-Axis you see the frames per seconds. The green graph displays the average minimum fps with pooling. The blue graph without pooling. You might ask why minimum? Because the minimum fps reflect the frame drops the player get resulting in a spiky or jerky experience. You want your game to run as smooth as possible.
As you can see in the graph, using pooling you increase the minimum fps and even keep it more steady. You can even see it better in the following boxplot.
Figure 2 - Boxplot: Shows the average minimum frames per second (fps) as quartile and median.
Memory Allocation
Unnecessary memory allocation is also some cause of frame drop, when the garbage collector collects the unused memory. At most cases you allocate new memory when instantiating new GameObjects or Components/Behaviour. In the following image you see the comparison of memory allocation using pooling and without.
Figure 3 - Line-Graph: Comparison of memory allocation (MB) over time with and without pooling.
On the X-Axis you see the time (20 ~ 1 second). On the Y-Axis you see the allocated memory in megabyte. The green graph displays the memory allocation with pooling. The blue graph without pooling. As you can see the memory stays more or less the same using pooling. Without utilizing pooling, memory allocation grows over time and can lead to delays at allocation, during garbage collection, or even cause game crashes due to excessively high memory usage.