Waiting for Pools
Been a little quiet on the blog lately. Never fear. This has nothing to do with a lack of work on or interest in Strange. Rather, the vast majority of my Strange attention has been focused on implementing a long-promised feature: Pools. My thinking on pooling changes almost constantly, so I’m hesitant to say too much yet about what form the final implementation will take (though you can always follow the commits on the ‘pool‘ branch). But what I can speak to are some of the uses of pools and how they will make your Strange life better.
What is a Pool? Why should I care? Can I please go read The Oatmeal or XKCD now?
No. Stay here. This is important.
Object creation can be expensive. In processing terms, expensive means that a process uses up performance resources or processing power that you’d rather have going to your amazing game. Every time you instantiate an object, a certain amount of memory gets allocated to storing the result (and a puppy dies…not that you care, you heartless bastard). As important, when you destroy an instance, that memory needs to be released. In Unity, most of this work is hidden from us via a process known as reference-counted garbage collection. That just means that once there are no references to an instance, that instance is marked for garbage collection (GC). At some interval, the garbage collector sweeps through and removes your discarded junk. The less GC you require, the more processing gets to go to the chills and thrills that make your game fun. You don’t want to waste resources, especially if you’re running on a mobile device where resources are very precious.
A pool is a mechanism for minimizing the creation and destruction of objects. Just as you recycle real-world refuse to make efficient use of resources, so a pool allows you to recycle (and be more efficient with) your instances. Simply put, you create some objects; when you’re done with one of them, instead of destroying it, you return it to the pool for later reuse.
OK, Got it. What’s this got to do with Strange?
Strange has been rather a bad citizen on the recycling front. While I’m not exactly clubbing baby seals, Strange doesn’t really play well as a delivery system for Events on your main game loop. The reason is that every time you dispatch an Event, you create a new TmEvent instance (Signals don’t have this problem). Every time you fire a Command, a new Command instance is instantiated. This is clean and simple (and why I wrote it this way on my first pass), but as you’ll now understand, not very environment-friendly. If you have an Event mapped to a Command running on your main game loop, you’re creating two throwaway objects 30x/second (or whatever your frame rate is). Depending on what else is happening in your loop, you might be creating/destroying lots more.
So the main use of pools for Strange is added efficiency. When pools are done, you should find Strange far better suited to use in a main game loop. Events and Commands will draw from pools and then be recycled, so there will be far less waste.
A secondary — though no less important — use case for the Pool is manual recycling. Currently you can map an injection as either Singleton, Value or Factory. Singleton and Value are efficient, since they both store a single instance. Factory is inherently wasteful, since you create a new instance every time you need one. In the new sexy, you’ll be able to map a Pool, and the Pool will create either a fixed number of instances, or else as many as you require, recycling the instances that you’re done with. Consider this in the context of a field of enemies: you can pool the enemy prefabs, then recycle instances as they vanish offscreen or are destroyed, claiming them back from the pool when you need new ones. This is much more efficient than throwing old objects away and re-instantiating.
So that’s what I’m up to. Hope you agree that it’s worth the time spent and the whisky drunk. I’ve been moving forward pretty fast in the last week and hope to have some Strange Pools to share on dev very soon!