Object pooling optimizations – not so much [yet]

[UPDATE] Clarified that I have two classes for my bullet. One which uses pooling, and another that does not use pooling.

So my object pooling optimizations don’t seem to be working.

I thought I would have seen some improvements in terms of my performance, but I’m just not seeing it. I think one issue is due to the fact that with more objects lying around, the garbage collector takes longer to run. Essentially, the pooling reduces how often the collector runs, but makes those runs more noticeable.

This is clear when viewing the debug screen within the game. Above, you’ll find a video that I recorded with my performance monitor running. The first clip illustrates the poor performance with pooling, and the second clip is without pooling, where I just instantiate the entities (bullets) and kill them as needed.

You can find my GitHub account here, and the applicable files here are for “bullet” and “pool“.

-----------------------


subscribe-to-youtube

4 thoughts on “Object pooling optimizations – not so much [yet]

  1. Like I said on Twitter, sorry it didn’t work out for you! Here are some differences that I noticed in our implementations that may or may not make a difference to why your performance didn’t improve and my did (though really maybe it’s not this at all):

    – You seem to create new objects (animation and timer) each time you “initialize” the bullet. Why not create these in “init” and then simply use them on initialization?

    – Your draw, check, etc, don’t seem to be limited to only running when the entity is “inUse” like the update method is – would this not mean they’re constantly running even when the bullet is not used?

    – I can’t see where the “killEntity” function you’re referencing is, but I’m guessing this just frees it up in the pool and doesn’t actually kill it? Otherwise the pool is semi pointless as you’re still killing lots of objects 🙂

    Anyway, maybe I just lucked out! I’m using object pooling again in the latest game, so we’ll see how it goes.

  2. Thanks again for taking the time to be so helpful along the way, I really do appreciate it.

    I have no doubt that my issues are stemming from the way I’ve implemented it, and not necessarily with your work. Besides, I would still be completely lost if it wasn’t for your site!

    As far as your questions:

    *** You seem to create new objects (animation and timer) each time you “initialize” the bullet. Why not create these in “init” and then simply use them on initialization? ***

    I could do it that way, yes. I’ve just moved both of those to “init”, where they are now created, but how do I actually use them within the “initialization” function?

    *** Your draw, check, etc, don’t seem to be limited to only running when the entity is “inUse” like the update method is – would this not mean they’re constantly running even when the bullet is not used? ***

    I’m confused here. I am doing it this way: I only allow “update” to be called on the bullets if they are being used. Unless I’m misunderstanding you?

    update: function (killTimer) {
    if (this.inUse === true) {
    this.killEntity(this.killTimer);
    this.parent();
    }
    },

    *** I can’t see where the “killEntity” function you’re referencing is, but I’m guessing this just frees it up in the pool and doesn’t actually kill it? Otherwise the pool is semi pointless as you’re still killing lots of objects ***

    killEntity” calls “this.Kill”, among other things.
    I see what you’re saying now! I didn’t realize that I did not replace “killEntity” with “ig.game.Pool.removeEntity(this);”, so that could largely be where my issue is stemming from. I’m killing a large number of objects at once. Doh! Let me make that change now.

  3. Very curious to see if that helps!

    Regarding point two – what I mean is, I see that you only allow “update” to be called on the bullets if they are being used, but what about things like your “draw”, “check”, etc? From the code it looks like you are NOT limiting them to only be called when the object is inUse like you are with the update function, so could they be running continuously on each bullet, even those you are not currently using?

    On the other hand, I’m not sure if things like draw, check, etc, are being called as part of the update itself, so maybe if you only call update if the object is “inUse” it applies to the rest as well. I had always assumed that update, check, draw, etc were totally independent of each other in the engine and would need to be wrapped inside that “if inUse” statement individually, but this could be wrong.

  4. Oh and point one – to use them in the initialization function you could call .set() on the timer when you initialize, and as for the animation you can just use it normally since it’s already defined. Eg you can see in my Flea entity that I define/create all the animations and timers (of which there are many) in init(), but then set them in initialize(): https://github.com/drakonka/Promiscuous-Flea/blob/master/lib/game/entities/flea.js

    I’m not sure how much difference this actually makes, my reasoning was that since we’re trying to minimize garbage, creating the objects only once for each entity and then simply reusing those objects would be more efficient than doing it over and over again each time you initialize it.

Leave a Reply