1 decade ago
Performance-wise, specifically considering garbage collection, is it worth creating a pool of entities to work with at the beginning of each game and setting them to active or inactive instead of spawning and killing new instances on demand?
And what are your thoughts on purposeful pooling variables and non-entity objects in general?
1 decade ago
Object pooling does wonders, especially for systems that spawn and destroy a lot of objects in a short amount of time (ala particle systems). The biggest performance hurdle for using HTML5 in games is garbage collection pauses, so you have to build your games to create as little garbage as possible.
For my current project, I had long garbage collection pauses roughly every thirty seconds or so, with Chrome being the worst off and IE being the best off. The biggest offender was my component based particle engine, which was basically the demo code that is made available when you buy Impact, but then expanded to use a compositional model. Particle entities were being created and then killed with kill(), so in a short amount of time a few hundred entities were created and then destroyed. By the time the garbage collector kicked in it had to clear the memory of a few thousand entities that only existed for a few seconds, which gave frequent (and long!) GC pauses. By storing the available objects in an array I was able to effectively eliminate GC pauses from the particle system.
Basically what I did was create a new array in the particle emitter and then populate it with 100 particle objects by default and create a new property variable to keep track of how many particles are available. When a particle is created, it is pulled from the array, and when it dies it is swapped with the last available particle - so the last available particle then becomes the next particle to be spawned and the one that died is pushed to the back of the array. If there is no available particle, then I push a new particle to the array and move it to the front of the array list so the cycle continues without pause. You then get a constant stream of particles going into and out of your array, and you are now re-using all of those particles which would have originally been going to the garbage collector.
Regarding pooling for non-entities, I haven't tested this at all yet. But I am certain I would do the same with this as I would particles IF that non-Entity object/function was something I needed to call fairly often and each call created a lot of garbage. If I only need a single var or create a small amount of objects then I will not bother setting up object pooling in that case, and would instead let the garbage collector feast =D.
lTyl do you have code to share?
1 decade ago
Yes, thanks a lot, lTyl!
I have been playing around with an object pool for my entities over the last couple of days. The difference seems too drastic to actually believe and I haven't done enough tests yet...Right now the timeline in DevTools still shows large GC spikes, but ImpactJS debug shows my system lag in the negative
and my FPS consistently between 57-60 (whereas before I'd have many negative spikes, with it going down to 35 or so). I have about 55 entities in existence at any one time throughout the game.
I'm not actually convinced that this is due to the pool. My code is inefficient and I just slapped a rough pooling add-in together. I definitely didn't expect this much of a change, so will need to do a lot more testing tomorrow. For anyone curious, here is the code I'm using for the pool: https://github.com/drakonka/Promiscuous-Flea/blob/master/lib/game/misc/pool.js
Code for the entities I am using this with is in this same repo - EntityFlea and EntityBabyflea
Page 1 of 1