apache / apache/druid

Skip `positions` indirection in `PooledTopNAlgorithm` when the aggregation size is small

Open
#8,335 0 comments 0 reactions 0 assignees View on GitHub
Area - Querying Contributions Welcome Performance
Dominant language
Java
Stars
14.1k
Forks
3.8k
Avg merge
2d 58m
Merged PRs (30d)
233

Description

`int[] positions` indirection in [`PooledTopNAlgorithm`](https://github.com/apache/incubator-druid/blob/566dc8c719489283f9190cefd6346bbb3f12955f/processing/src/main/java/org/apache/druid/query/topn/PooledTopNAlgorithm.java) seems wasteful, especially when the aggregation size itself is just 4 or 8 bytes, as is the case of float/double/long Min/Max/Sum aggregations, leading to 33%/50% higher memory usage than needed for processing. It's role to initialize the aggregation at the right moment 1) can be replaced with `BitSet dimIndexInitialized`; 2) may be unnecessary/wasteful itself for aggregators which zero the memory as their initialization step: it may be faster to just stream set the whole buffer's memory to zero at the beginning of processing.

There is a locality concern for larger aggregations: `positions` facilitate putting the hottest aggregations together at the beginning of the buffer, thus improving the cache and the TLB utilization. This positive effect is completely canceled by the `positions` itself (access to which is still random) for aggregations of 4 bytes and almost for sure for aggregations of 8 bytes. After that, there should be experiments showing at which aggregation size the positive effect of `positions` outweigh its negative effect (which also diminishes with the growth of the aggregation size): its likely to be somewhere between 12 and 32 bytes, but benchmarking is required to determine the threshold more precisely.

Contributor guide

Open the contributing guide

Research direction

Start by reading processing/src/main/java/org/apache/druid/query/topn/PooledTopNAlgorithm.java, focusing on how positions initializes and orders aggregations. Benchmark small aggregation sizes, especially 4, 8, 12, and 32 bytes, against the alternatives described in the issue. Done means selecting and implementing a threshold or initialization strategy supported by measurements, while preserving the locality benefit for larger aggregations.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
performance
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.