perf(runend): Scan short-run filter masks sequentially - #9763
Conversation
Signed-off-by: Will Manning <will@willmanning.io>
Merging this PR will regress 5 benchmarks
|
Signed-off-by: Will Manning <will@willmanning.io>
Signed-off-by: Will Manning <will@willmanning.io>
|
Closing this prototype because the benchmark results do not justify its complexity. The sequential scan was 9–17% faster for 16–32-row runs on AArch64. The gain fell to 1–6% around 64-row runs. It became slower for longer runs. Results on AVX2 and AVX-512 were neutral or slower. The implementation adds a second filter path and about 500 lines. We did not measure an improvement in an end-to-end workload. We will keep the branch as a record of the experiment. |
|
I think you want to adjust the compressor to give RLE edge despite bigger size |
Summary
RunEnd filtering currently counts selected rows separately inside every run. For short runs, each
BitBuffer::count_rangecall repeats alignment and range setup.The kernel now scans the mask once with a sequential cursor when the average run length is at most 64 rows. Longer runs retain the existing range-popcount path. Sparse filters retain the existing direct-take path.
Changes
The benchmark compares production dispatch, direct take, the previous range scan, and the sequential scan. It covers production-width run ends, multiple array lengths, uniform and skewed runs, selectivity, clustered masks, and Dictionary values.
On an Apple M4 Max, the sequential path was 8% to 35% faster through an average run length of 64. It was neutral at 128 rows and 2% to 41% slower at 256 and 512 rows. Skewed runs showed the same crossover, so the threshold preserves the old path before the regression.
Conformance and oracle tests cover both branches, bitmap offsets, irregular runs, nulls, and sliced arrays. CodSpeed will provide the x86_64 comparison before this draft becomes ready.
🤖 Generated with OpenAI Codex