This should be an easy one … I have three steaming lumps of glorious imperative code that execute code to populate a cache based on entries already in the cache.
These lumps are essentially an imperative sequence of C-style nested loops over integers, that pull things out of the cache for some choices of keys and push the results back into the cache under derived keys.
This is not a simple Cartesian product of key indices, though.
So:
LOOP 1 > LOOP 1.1 > LOOP 1.2;
LOOP 2 > LOOP 2.1 > LOOP 2.2;
LOOP 3 > LOOP 3.1 > LOOP 3.2
makes one lump, and there are three lumps that work on completely distinct families of cache keys.
So no results are shared between the computations done in the lumps.
Each loop can work on circa 100 000 items. Heap and stack usage are bounded in each lump.
The cache is essentially a wrapper around two arrays. It couldn’t be more like C if it tried. There are no concurrency locks, as arrays are used and the keys don’t clash.
It has to run as fast as possible on a single desktop computer.
So if I wanted to run the lumps in parallel with as little overhead as possible, what would be the obvious way?
I could do the Cats thing and use IO
, but that seems like overkill - I don’t need the cancellable model, and as memory isn’t an issue for each lump, I’m not concerned about a computation going wild, having side effects other than populating the cache or throwing exceptions. Think computation threads rather than asynchronous effects.
I do want to avoid spinning up threads via the Java API for each lump directly - there is an outer loop around the whole thing, and there is use of thread pooling going on elsewhere, so I’d like to join an existing thread pool.
I’m not terribly keen on going the Executor
/ ExecutionService
route, so my current thinking for tomorrow is to make three Future
instances and gang them together as an applicative functor to get parallel execution.
Any suggestions as to a more direct and performant approach?