feat: specialize primitive sums for constant and run-end arrays - #9821
feat: specialize primitive sums for constant and run-end arrays#9821connortsui20 wants to merge 1 commit into
Conversation
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Merging this PR will regress 2 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | random_i16[0.8] |
75.5 µs | 93.9 µs | -19.65% |
| ❌ | WallTime | mul_u32_nonnull_avx512 |
5.5 µs | 6.3 µs | -11.32% |
| ⚡ | Simulation | random_i8[0.5] |
91.4 µs | 68.1 µs | +34.17% |
| ⚡ | WallTime | dict_canonicalize_gt_u8_neon[1000000] |
567.1 µs | 486.8 µs | +16.5% |
| ⚡ | WallTime | dict_canonicalize_gt_u8_neon[16000000] |
9.3 ms | 8 ms | +15.7% |
| 🆕 | Simulation | grouped_constant_fallback[1] |
N/A | 161.6 ms | N/A |
| 🆕 | Simulation | grouped_constant_fallback[128] |
N/A | 1.4 ms | N/A |
| 🆕 | Simulation | grouped_constant_fallback[2] |
N/A | 81 ms | N/A |
| 🆕 | Simulation | grouped_constant_fallback[8] |
N/A | 20.3 ms | N/A |
| 🆕 | Simulation | grouped_constant[1] |
N/A | 13 ms | N/A |
| 🆕 | Simulation | grouped_constant[128] |
N/A | 211.8 µs | N/A |
| 🆕 | Simulation | grouped_constant[2] |
N/A | 6.5 ms | N/A |
| 🆕 | Simulation | grouped_constant[8] |
N/A | 1.7 ms | N/A |
| 🆕 | Simulation | grouped_runend_fallback[1, 1024] |
N/A | 5.2 ms | N/A |
| 🆕 | Simulation | grouped_runend_fallback[1, 4] |
N/A | 5.8 ms | N/A |
| 🆕 | Simulation | grouped_runend_fallback[1, 64] |
N/A | 5.2 ms | N/A |
| 🆕 | Simulation | grouped_runend_fallback[128, 1024] |
N/A | 282.5 µs | N/A |
| 🆕 | Simulation | grouped_runend_fallback[128, 4] |
N/A | 853.8 µs | N/A |
| 🆕 | Simulation | grouped_runend_fallback[128, 64] |
N/A | 288.8 µs | N/A |
| 🆕 | Simulation | grouped_runend_fallback[2, 1024] |
N/A | 2.7 ms | N/A |
| ... | ... | ... | ... | ... | ... |
ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ct/constant-runend-sum (ae99ee8) with develop (e3b8eb2)
Footnotes
-
218 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
Split into two independent draft PRs: constant sums #9822 and run-end sums #9823.
Summary
Computes primitive
SumandSumV2over constant and run-end arrays without expanding repeated values, including grouped aggregation. Decimal inputs keep their existing paths. Weighted floating-point sums can round differently from repeated addition, as existing constant sums do.Changes
Run-end sums weight values by their run lengths, use fused multiply-add to preserve finite cancellation, and share a run cursor across fixed-size groups. Constant groups reuse scalar multiplication, and both encodings use helpers for
SumV2partial states.Tests and validation
New tests compare the kernels with decoded primitive arrays and cover nulls, slices, empty groups, overflow, NaNs, finite cancellation, and decimal fallback.
cargo nextest run -p vortex-array -p vortex-runend --lib: 3,679 passed, 1 skipped.cargo test --doc -p vortex-array -p vortex-runend: passed.cargo clippy --all-targets --all-features -- -D warnings: passed.cargo +nightly fmt -p vortex-array -p vortex-runend -- --checkandtaplo fmt --check: passed.vortex-duckdbandvortex-ffi, outside this diff.Benchmark results
Local medians on
aarch64-apple-darwinwith Rust 1.98.0, usingcargo bench -p vortex-runend --bench run_end_sum -- --sample-count 100. Both modes use revisionae99ee84fe65813994cd432a495a99ae7e84b705, with the baseline disabling the new encoding kernels in its session.Each input has 16,384
i32elements. The run-end cases use nullable values and 64-element runs. Grouped timings include finalization to a primitive array.The benchmark also covers run lengths 4 and 1,024 and group sizes 1 and 8.