The Java collections framework is great. You can create maps, sets, lists with various element types, various performance characteristics (e.g. if you want O(1) insert, use a linked list), iterate over them, and you can decorate them to give them other behaviors.
But suppose that you want to create a high-performance, memory efficient immutable list of integers? You’d write
There will be 6 objects allocated in the JVM: three
Object to hold the
Integer values, an
UnmodifiableRandomAccessList. Not to mention the
Integer used to construct the list and
quickly thrown away.
The resulting list is no longer high-performance. A call to say
= list.get(2) requires 3 method calls
Integer.intValue) and 3 indirections. And the sheer number of
objects created reduces the chance that a given stretch of code will
be able to operate solely from the contents of L1 cache.
So, what next? Should I write my own class, like this?
Well, maybe. But there are rather a lot of variations to cover, and each one needs to be hand-coded and tested.
None of the libraries supports features such as maps with two or more
keys, unmodifiable collections, synchronized collections, flat
collections (similar to Apache
It’s not surprising that they don’t: each combination
of features would require its own class, so the size of the jar file
would grow exponentially.
So, I’d like to propose an alternate approach. You configure a factory, specifying the precise kind of collection you would like, and the factory generates the collection class in bytecode. You can use the factory to quickly create as many instances of the collection as you wish. The collection implements the Java collections interfaces, plus additional interfaces that allow you to efficiently access the collection without boxing/unboxing.
The above example would be written as follows:
Variants are expressed as
FactoryBuilder FactoryBuilder.keyType(Class...)(for maps only)
FactoryBuilder FactoryBuilder.valueType(Class...)(for maps only)
FactoryBuilder FactoryBuilder.elementType(Class...)(for list and set only)
FactoryBuilder FactoryBuilder.sorted(boolean)(cf. the difference between
FactoryBuilder FactoryBuilder.deterministic(boolean)(cf. the difference between
FactoryBuilder FactoryBuilder.fixedSize(boolean)(cf. the difference between
And so forth. Additional variants could be added as the project evolved. Templates could be fine-tuned for particular combinations of variants.
The projects I mentioned above clearly use a template system, and we could use and extend those templates. The janino facility can easily convert the generated java code into bytecode. And the JVM would be able to apply JIT (just-in-time compilation) to these classes; in fact, these classes would be more amenable to compilation, because they would be compact and final.
The existing projects have invested a lot of effort designing high-performance collections. I’d like to build on that work; this project could even be an extension to those projects.
I’d like to hear if you’re interested in working with me on this.