For the past two weeks I’ve been trying to perfect object pooling with ImpactJS in order to increase performance for my Win8 port of Super Rawr-Type. You can find the latest (working) Win8 build of Super Rawr-Type on my GitHub. I finally created a version of object pooling for my bullets and enemy bullets which worked well, but I knew that there was room for improvement.
So I spent another week going back at it; I refactored a lot of code, cut the number of lines in code in half, and seemed to have improved performance a bit. Here is what that class looks like. In the end though, it all seemed to be in vain: My performance, even with object pooling was suffering, but I I’ve finally discovered why.
Why object pooling was not the silver bullet
When my level initializes I am loading a large number of entities for my object pools, namely bullets for each enemy. At first I was using around 60 bullets for each type of enemy (and I have 4 enemies), so the total number of entities created during the beginning of my level was hovering around 250, which my ship’s bullets and background entities included.
I didn’t think this would be a problem, as I’m only calling update and draw on these objects when they are on screen. But this didn’t resolve my performance issue. What seems to be happening is that Impact is constantly looking through the game’s entity array, and that seems to have a huge performance hit. I tested this by changing the number of entities (bullets) spawned (but inactive) during the game’s loadLevel call.
As I decreased the number of entities created, my performance increased considerably. What I’ve decided to do instead is to pre-load 10 bullets for each enemy, therefore cutting down on the number of entities at initialization. What this does is allow the enemy object pool to continue to use then un-use bullets in the pool, and when necessary it can spawn more when needed.
I chose this approach because it allows flexibility in that I’m not having to constantly create/destroy nearly as many objects as had to before. It also cuts down on the number of entities loaded at any given time.
Ed Di Geronimo explained it best to me: “Pooling tends to work great when you have a bad garbage collector, like on XBLIG or WP7. Doesn’t help much with a good collector”
It was after I looked through the source code for X-Type that I realized object pooling wasn’t particularly necessary. Dominic Szablewski (also the creator of the ImpactJS framework) doesn’t use pooling for his shooter, yet maintains 60fps, AND with WebGL.
Other performance improvements
2) Greatly decreased the number of particles triggered
I took a day to sift through various particle code for Impact and found that object pooling wouldn’t help me here either, for the reasons listed above. In the end I chose to just limit the number of particles on screen at once, cutting it down from 25 particles each time an object is hit, to 5. Furthermore, I realized that I mistakenly was triggering 2x as many particles in certain instances due to erroneous code of my own.