Repository navigation
perf: batch fragmented CASE branch execution - #9820
Conversation
Merging this PR will regress 6 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | case_when_nary_10_conditions[1000] |
266 µs | 369.9 µs | -28.07% |
| ❌ | Simulation | case_when_nary_equality_lookup[1000] |
237.4 µs | 296.7 µs | -19.98% |
| ❌ | Simulation | case_when_nary_3_conditions[1000] |
167.6 µs | 205.7 µs | -18.52% |
| ❌ | Simulation | case_when_nary_early_dominant[1000] |
167.1 µs | 204.6 µs | -18.34% |
| ❌ | Simulation | case_when_nary_equality_lookup[10000] |
379.5 µs | 454.9 µs | -16.58% |
| ❌ | WallTime | bitpack_blocked_compress_avx2 |
6.7 µs | 7.6 µs | -11.92% |
| ⚡ | Simulation | case_when_fragmented[400] |
507.1 µs | 183.9 µs | ×2.8 |
| ⚡ | WallTime | mul_u64_nonnull_neon |
39.7 µs | 28.7 µs | +38.35% |
| ⚡ | Simulation | case_when_fragmented[100] |
203.3 µs | 157.9 µs | +28.77% |
| ⚡ | WallTime | multiply_shapes_neon[(32768, PerRowPerRow)] |
38.7 µs | 32.6 µs | +18.96% |
| ⚡ | WallTime | mul_i64_nonnull_neon |
38.6 µs | 32.6 µs | +18.41% |
| ⚡ | Simulation | case_when_nary_10_conditions[10000] |
500.7 µs | 448.9 µs | +11.53% |
| 🆕 | Simulation | case_when_decimal_product[1] |
N/A | 230 µs | N/A |
| 🆕 | Simulation | case_when_decimal_product[64] |
N/A | 206.3 µs | N/A |
| 🆕 | Simulation | case_when_string_values[1] |
N/A | 192.8 µs | N/A |
| 🆕 | Simulation | case_when_string_values[64] |
N/A | 180.6 µs | N/A |
| 🆕 | Simulation | case_when_decimal_product[8] |
N/A | 208.2 µs | N/A |
| 🆕 | Simulation | case_when_string_values[8] |
N/A | 189.5 µs | N/A |
| Simulation | bench_compare_primitive[(10000, 2)] |
< 1 ns | < 1 ns | N/A |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ngates/batched-case-execution (f83e38f) with develop (2b4c682)2
Footnotes
-
409 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. ↩
-
No successful run was found on
develop(1ee4e3a) during the generation of this report, so 2b4c682 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
Polar Signals Profiling ResultsLatest Run
Previous Runs (17)
Powered by Polar Signals Cloud |
Benchmarks: FineWeb NVMe 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.993x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.002x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.090x ➖, 1↑ 4↓)
duckdb / parquet / ns (1.001x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: TPC-H SF=10 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.993x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.000x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.016x ➖, 0↑ 2↓)
duckdb / parquet / ns (0.995x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: Clickbench Sorted on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.003x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.994x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.007x ➖, 0↑ 0↓)
duckdb / parquet / ns (0.999x ➖, 0↑ 0↓)
File Size Changes (100 files changed, -0.0% overall, 44↑ 56↓)
Totals:
|
Benchmarks: Statistical and Population Genetics 📖Commits: PR How to read Verdict and Engines
duckdb / vortex-file-compressed / ns (1.212x ❌, 0↑ 2↓)
duckdb / parquet / ns (1.009x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: Clickbench on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.007x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.997x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.006x ➖, 1↑ 3↓)
duckdb / parquet / ns (1.005x ➖, 1↑ 1↓)
No file size changes detected. |
Benchmarks: FineWeb S3 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.942x ➖, 1↑ 0↓)
datafusion / parquet / ns (1.009x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.200x ➖, 0↑ 2↓)
duckdb / parquet / ns (1.001x ➖, 0↑ 0↓)
|
Benchmarks: TPC-H SF=1 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.001x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.997x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.009x ➖, 0↑ 1↓)
duckdb / parquet / ns (1.008x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: PolarSignals Profiling 📖Commits: PR datafusion / vortex-file-compressed / ns (0.998x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: TPC-H SF=1 on S3 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.585x ✅, 7↑ 1↓)
datafusion / parquet / ns (1.008x ➖, 0↑ 1↓)
duckdb / vortex-file-compressed / ns (0.763x ➖, 4↑ 0↓)
duckdb / parquet / ns (0.880x ➖, 3↑ 0↓)
|
Benchmarks: TPC-DS SF=1 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.997x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.999x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (0.997x ➖, 3↑ 1↓)
duckdb / parquet / ns (0.999x ➖, 2↑ 2↓)
No file size changes detected. |
|
This PR has been marked as stale because it has been open for 14 days with no activity. Please comment or remove the stale label if you wish to keep it active, otherwise it will be closed in 7 days |
aa123dd to
8c8f65c
Compare
8c8f65c to
9c7a9f5
Compare
…ution Signed-off-by: Nicholas Gates <nick@nickgates.com>
CASE WHEN accepts THEN and ELSE values that differ in nested nullability, but its output dtype only merged the top-level nullability. When a nested field was nullable on one side only, reading a row with a null in that field failed with a cast error. - Merge nullability at every nesting level in `return_dtype`. Use the helper that `zip` already uses. - Give `merge_case_branches` the output dtype and the ELSE mask from `execute`. Do not compute them again. - Cast each value once in `merge_runs`, not once for each span. - Test compact merges with two branches plus ELSE rows. Signed-off-by: Robert Kruszewski <github@robertk.io> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
02a61c9 to
f83e38f
Compare
Benchmarks: PolarSignals Profiling 📖Commits: PR datafusion / vortex-file-compressed / ns (1.000x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: FineWeb NVMe 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.007x ➖, 0↑ 1↓)
datafusion / vortex-compact / ns (0.907x ➖, 2↑ 0↓)
datafusion / parquet / ns (1.006x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.035x ➖, 2↑ 3↓)
duckdb / vortex-compact / ns (1.060x ➖, 1↑ 3↓)
duckdb / parquet / ns (1.007x ➖, 0↑ 1↓)
No file size changes detected. |
Benchmarks: TPC-H SF=1 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.995x ➖, 0↑ 0↓)
datafusion / vortex-compact / ns (0.995x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.998x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.018x ➖, 1↑ 2↓)
duckdb / vortex-compact / ns (0.996x ➖, 0↑ 1↓)
duckdb / parquet / ns (0.996x ➖, 0↑ 0↓)
duckdb / duckdb / ns (0.983x ➖, 1↑ 1↓)
No file size changes detected. |
Benchmarks: Clickbench Sorted on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.990x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.997x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (0.976x ➖, 2↑ 1↓)
duckdb / parquet / ns (0.978x ➖, 0↑ 0↓)
duckdb / duckdb / ns (0.993x ➖, 0↑ 0↓)
File Size Changes (201 files changed, -0.0% overall, 92↑ 109↓)
Totals:
|
Benchmarks: FineWeb S3 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.177x ➖, 1↑ 4↓)
datafusion / vortex-compact / ns (1.074x ➖, 1↑ 2↓)
datafusion / parquet / ns (1.234x ➖, 0↑ 3↓)
duckdb / vortex-file-compressed / ns (1.010x ➖, 0↑ 0↓)
duckdb / vortex-compact / ns (1.023x ➖, 0↑ 0↓)
duckdb / parquet / ns (1.006x ➖, 0↑ 0↓)
|
Benchmarks: Clickbench on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.001x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.999x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.028x ➖, 0↑ 6↓)
duckdb / parquet / ns (1.008x ➖, 3↑ 2↓)
duckdb / duckdb / ns (0.994x ➖, 0↑ 0↓)
File Size Changes (1 files changed, -0.0% overall, 0↑ 1↓)
Totals:
|
Benchmarks: Appian on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.998x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.003x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.003x ➖, 0↑ 0↓)
duckdb / parquet / ns (0.994x ➖, 0↑ 0↓)
duckdb / duckdb / ns (1.005x ➖, 0↑ 0↓)
File Size Changes (1 files changed, -0.0% overall, 0↑ 1↓)
Totals:
|
Benchmarks: TPC-DS SF=1 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.002x ➖, 0↑ 1↓)
datafusion / vortex-compact / ns (1.003x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.002x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (0.997x ➖, 4↑ 1↓)
duckdb / vortex-compact / ns (1.003x ➖, 2↑ 3↓)
duckdb / parquet / ns (0.994x ➖, 4↑ 0↓)
duckdb / duckdb / ns (0.968x ➖, 13↑ 1↓)
No file size changes detected. |
Benchmarks: TPC-H SF=10 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.000x ➖, 0↑ 0↓)
datafusion / vortex-compact / ns (0.996x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.000x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.005x ➖, 0↑ 0↓)
duckdb / vortex-compact / ns (0.992x ➖, 0↑ 0↓)
duckdb / parquet / ns (0.996x ➖, 0↑ 0↓)
duckdb / duckdb / ns (1.005x ➖, 0↑ 1↓)
No file size changes detected. |
Benchmarks: Statistical and Population Genetics 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.002x ➖, 0↑ 0↓)
datafusion / vortex-compact / ns (1.005x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.003x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (0.999x ➖, 0↑ 0↓)
duckdb / vortex-compact / ns (0.998x ➖, 0↑ 0↓)
duckdb / parquet / ns (0.997x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: TPC-H SF=1 on S3 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.137x ➖, 0↑ 3↓)
datafusion / vortex-compact / ns (1.094x ➖, 0↑ 2↓)
datafusion / parquet / ns (1.064x ➖, 1↑ 2↓)
duckdb / vortex-file-compressed / ns (1.137x ➖, 0↑ 3↓)
duckdb / vortex-compact / ns (1.031x ➖, 1↑ 2↓)
duckdb / parquet / ns (1.005x ➖, 0↑ 0↓)
|
Benchmarks: Vortex queries 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.002x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.014x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.008x ➖, 0↑ 0↓)
duckdb / parquet / ns (1.003x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: TPC-H SF=10 on S3 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.997x ➖, 2↑ 3↓)
datafusion / vortex-compact / ns (0.996x ➖, 1↑ 2↓)
datafusion / parquet / ns (1.126x ➖, 0↑ 5↓)
duckdb / vortex-file-compressed / ns (1.052x ➖, 0↑ 0↓)
duckdb / vortex-compact / ns (1.089x ➖, 0↑ 1↓)
duckdb / parquet / ns (1.115x ➖, 0↑ 0↓)
|
Why
Fragmented CASE selections can repeatedly execute lazy branch expressions for tiny runs or individual rows. Batch those selections so branch evaluation stays columnar, while keeping the existing low-overhead approach for coarse runs.
Changes
Validation
cargo nextest run -p vortex-array: 3,453 passed, one skipped (including 55 CASE tests).cargo clippy -p vortex-array --all-targets --all-features -- -D warnings: passed.cargo +nightly fmt --allandgit diff --check: passed.cargo bench -p vortex-array --bench expr_case_when -- --sample-count 30: completed, including simple, n-ary, early-exit, fragmented, and coarse-run controls.On this revision, 65,536-row alternating decimal-product and string cases have medians of 165.5 µs and 157.1 µs. These are candidate-only measurements, not a fresh comparison against develop. Earlier paired experiments motivated the change, but also found small n-ary regressions; this is not a claim of uniform improvement.
Review considerations
The 128-rows-per-run heuristic is empirical. Compact assembly adds temporary output/permutation storage; no memory-saving claim is made. The shared scalar-function filter rule broadens selection pushdown, so its contract and deeply nested expression behavior deserve particular review.
Ported and validated with Codex. No dependency changes or unrelated Vortex experiments are included.