Chunk-oriented architecture: bulk data processing

Process blocks of data instead of individual cells for better performance

vs
Cell-by-cell (traditional)
ColumnSource: Values
42
17
93
28
... (millions more, one at a time)
Each cell: virtual method call
Poor cache locality
Can't vectorize
Chunk-based (Deephaven)
ColumnSource (ChunkSource)
Chunk (bulk read, configurable size)
... 4092 more values ...
One call for thousands of cells
Sequential memory access
JIT can vectorize (SIMD)
How chunk-based processing works
1. ColumnSource
getChunk(context,
  rowSequence)
2. Chunk buffer
Typed array wrapper
IntChunk, DoubleChunk,
ObjectChunk, etc.
3. Bulk operation
Process entire chunk
Filter, aggregate,
transform, etc.
4. Result chunk
Output buffer
Reused from pool or
written to destination
Chunk pooling: reduce garbage collection
Chunks are reusable buffers managed by a pool to avoid allocating temporary objects
Available
acquire()
In use
release()
Returned
Performance benefits
Amortized overhead
One method call for thousands of cells
vs. thousands of individual calls
~1000x fewer calls
Vectorization
Sequential memory allows
SIMD operations
Process 4-8 values per instruction
Cache efficiency
Contiguous data improves
L1/L2/L3 cache hit rates
Fewer memory stalls
Example: filtering with chunks
// Instead of: for (long key : rowSet) { if (predicate(getValue(key))) { ... } }
// Chunks do: Chunk values = source.getChunk(context, rowSequence);
//            bulkFilter(values, predicate, outputKeys);  // Process entire chunk at once