Skip to content

Execute primitive comparisons with RowFn - #9346

Draft
connortsui20 wants to merge 6 commits into
ct/row-fn-numeric-operatorsfrom
ct/row-fn-primitive-comparisons
Draft

Execute primitive comparisons with RowFn#9346
connortsui20 wants to merge 6 commits into
ct/row-fn-numeric-operatorsfrom
ct/row-fn-primitive-comparisons

Conversation

@connortsui20

@connortsui20 connortsui20 commented Aug 11, 2026

Copy link
Copy Markdown
Member

Rationale for this change

Moves primitive comparisons to RowFn where native measurements support it. The faster fused x86 path remains for selected 64-bit comparisons.

What changes are included in this PR?

The columnar path handles equality for i64, u64, and f64, all i64 and f64 operators, and mixed-constant u64 operators. Tests force both paths over identical values, validity, NaN, signed zero, and constant positions. Their encoding difference is intentional: columnar execution materializes a BoolArray, while row execution keeps a lazy mask chain.

On Rust 1.97.1 with one CGU and fat LTO, per-row u8 and f32 cases improve by 23.5% and 15.9%. Per-row i32, f32 equality, and u64 regress by 22–26%. Mixed-constant i32 and u8 regress by 8.3–8.5x because LLVM 22 emits scalar loops for the RowFn path.

What APIs are changed? Are there any user-facing changes?

There are no public API changes. The path selector and forced-path controls remain internal.

@connortsui20 connortsui20 changed the title ct/row fn primitive comparisons Execute primitive comparisons with RowFn Aug 11, 2026
@codspeed-hq

codspeed-hq Bot commented Aug 11, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 28.98%

⚡ 2 improved benchmarks
❌ 46 regressed benchmarks
✅ 1939 untouched benchmarks
🆕 11 new benchmarks
⏩ 89 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation case_when_nary_10_conditions[10000] 753.7 µs 1,809 µs -58.34%
Simulation baseline_eq[4, 65536] 586.1 µs 1,221.2 µs -52.01%
Simulation baseline_lt[4, 65536] 601.6 µs 1,220.6 µs -50.72%
Simulation case_when_nary_equality_lookup[10000] 522.2 µs 1,056.2 µs -50.56%
Simulation baseline_eq[16, 65536] 690.2 µs 1,324.3 µs -47.88%
Simulation baseline_lt[16, 65536] 705.8 µs 1,326.4 µs -46.79%
Simulation case_when_nary_early_dominant[10000] 387.6 µs 708.1 µs -45.26%
Simulation case_when_nary_3_conditions[10000] 389.3 µs 711.1 µs -45.25%
Simulation case_when_all_false[100000] 1.1 ms 2 ms -44.64%
Simulation case_when_all_true[100000] 1.1 ms 2 ms -44.45%
Simulation case_when_simple[100000] 1.2 ms 2.1 ms -44.22%
Simulation case_when_without_else[100000] 1.3 ms 2.2 ms -42.54%
Simulation case_when_nary_10_conditions[1000] 410.7 µs 673.7 µs -39.04%
Simulation case_when_all_false[10000] 212 µs 323 µs -34.36%
Simulation case_when_all_true[10000] 216.6 µs 327.2 µs -33.82%
Simulation baseline_lt[4, 1024] 95.5 µs 139 µs -31.26%
Simulation case_when_simple[10000] 245.8 µs 352.7 µs -30.3%
Simulation case_when_nary_equality_lookup[1000] 316.3 µs 453 µs -30.17%
Simulation baseline_eq[4, 1024] 94.9 µs 135.4 µs -29.91%
Simulation bench_compare_sliced_dict_primitive[(5000, 10000)] 183.7 µs 261 µs -29.62%
... ... ... ... ... ...

ℹ️ 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/row-fn-primitive-comparisons (213f008) with ct/row-fn-numeric-operators (f8670a8)2

Open in CodSpeed

Footnotes

  1. 89 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.

  2. No successful run was found on ct/row-fn-numeric-operators (f108cdd) during the generation of this report, so cac689c was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@connortsui20
connortsui20 force-pushed the ct/row-fn-primitive-comparisons branch from 04d477e to 2db7f1e Compare August 11, 2026 16:04
@connortsui20
connortsui20 marked this pull request as ready for review August 11, 2026 16:05
@connortsui20
connortsui20 marked this pull request as draft August 11, 2026 16:24
@connortsui20
connortsui20 force-pushed the ct/row-fn-primitive-comparisons branch from 2db7f1e to 496e733 Compare August 11, 2026 17:12
@connortsui20
connortsui20 force-pushed the ct/row-fn-primitive-comparisons branch from 496e733 to 654caec Compare August 11, 2026 17:35
Use RowFn for primitive comparisons while retaining fused x86 bit-packing for the measured wide ordered cases where LLVM generates faster code.

Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Cover lane widths, equality, nullability, and both constant operand positions for primitive comparison dispatch.

Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
@connortsui20
connortsui20 force-pushed the ct/row-fn-primitive-comparisons branch from 654caec to 213f008 Compare August 11, 2026 19:36
@connortsui20

Copy link
Copy Markdown
Member Author

Here are the local primitive-comparison benchmark results from the final Rust 1.97.1 run.

The comparison used a develop baseline with benchmark-only backfills (1edd0fca) and the full RowFn stack (8ca9fc73). Later stack layers do not change primitive comparison source, but unrelated code-placement effects can still affect these binaries.

The machine was an AMD Ryzen 9 7950X running Linux. The build used rustc 1.97.1, LLVM 22.1.6, one CGU, fat LTO, and -C target-cpu=native. Each target used two warm runs and seven alternating measured pairs. Each process used 100 samples with a 0.25–0.5 second measurement window on CPU 4.

Negative changes are faster. The values are medians across the seven paired runs.

The per-row u8 and f32 cases improve by 23.52% and 15.85%. The per-row i32, f32 equality, and u64 cases regress by 21.92–25.88%. LLVM 22 emits scalar loops for the mixed-constant i32 and u8 RowFn paths, which makes those cases 8.32–8.53x slower.

All primitive-comparison results: 25 cases
Benchmark Baseline RowFn stack Change
compare_u8_constant 3.689 µs 31.480 µs +752.81%
compare_i32_constant 3.779 µs 31.460 µs +731.88%
compare_f32_eq 4.559 µs 5.729 µs +25.88%
compare_i32 4.549 µs 5.709 µs +25.34%
compare_u64 9.509 µs 11.680 µs +21.92%
compare_struct_eq 179.400 µs 193.800 µs +8.06%
compare_string_eq 31.750 µs 32.260 µs +1.64%
compare_int_eq 9.329 µs 9.449 µs +1.39%
compare_u64_constant 4.919 µs 4.919 µs +1.38%
compare_float_eq 9.459 µs 9.539 µs +1.28%
compare_int_constant 4.949 µs 4.939 µs +1.07%
compare_string_constant 31.460 µs 31.660 µs +0.79%
compare_int_nullable 9.779 µs 9.799 µs +0.72%
compare_u64_eq 9.459 µs 9.529 µs +0.42%
compare_struct_lt 179.200 µs 179.500 µs +0.11%
compare_int 9.649 µs 9.599 µs +0.11%
compare_decimal 41.610 µs 41.590 µs -0.10%
compare_float 11.510 µs 11.370 µs -0.26%
compare_string_lt 33.550 µs 33.410 µs -0.42%
compare_bool_nullable 1.619 µs 1.599 µs -0.62%
compare_bool_constant 719.7 ns 709.7 ns -1.39%
compare_bool 1.429 µs 1.419 µs -1.39%
compare_int_constant_lhs 5.059 µs 4.879 µs -2.49%
compare_f32 6.949 µs 5.849 µs -15.85%
compare_u8 3.859 µs 2.949 µs -23.52%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant