In a game for Android written in Scala, I have plenty of objects that I want to pool. First I tried to have both active (visible) and non active instances in the same pool; this was slow due to filtering that both causes GC and is slow.
So I moved to using two data structures, so when I need to get a free instance, I just take the first from the passive pool and add it to the active pool. I also fast random access to the active pool (when I need to hide an instance). I’m using two ArrayBuffers for this.
So my question is: which data structure would be best for this situation? And how should that (or those) specific data structure(s) be used to add and remove to avoid GC as much as possible and be efficient on Android (memory and cpu constraints)?
The best data structure is an internal list, where you add
to every class. The non-active instances then become what’s typically called a “free list”, while the active ones become a singly-linked list a la
List.This way your overhead is exactly one pointer per object (you can’t really get any less than that), and there is no allocation or GC at all. (Unless you want to implement your own by throwing away part or all of the free list if it gets too long.)
You do lose some collections niceness, but you can just make your class be an iterator:
is all you need given that
var. (Well, andextends Iterator[MyClass].) If your pool sizes are really quite small, sequential scanning will be fast enough.If your active pool is too large for sequential scanning down a linked list and elements are not often added or deleted, then you should store them in an
ArrayBuffer(which knows how to remove elements when needed). Once you remove an item, throw it on the free list.If your active pool turns over rapidly (i.e. the number of adds/deletes is similar to the number of random accesses), then you need some sort of hierarchical structure. Scala provides an immutable one that works pretty well in
Vector, but no mutable one (as of 2.9); Java also doesn’t have something that’s really suitable. If you wanted to build your own, a red-black or AVL tree with nodes that keep track of the number of left children is probably the way to go. (It’s then a trivial matter to access by index.)