Skip to content

Execute primitive numeric operators with RowFn - #9345

Draft
connortsui20 wants to merge 2 commits into
ct/row-fn-batchfrom
ct/row-fn-numeric-operators
Draft

Execute primitive numeric operators with RowFn#9345
connortsui20 wants to merge 2 commits into
ct/row-fn-batchfrom
ct/row-fn-numeric-operators

Conversation

@connortsui20

@connortsui20 connortsui20 commented Aug 11, 2026

Copy link
Copy Markdown
Member

Rationale for this change

Makes primitive arithmetic the first production user of RowFn. Binary keeps its registered identity and existing scalar-function hooks.

What changes are included in this PR?

Checked add, subtract, and multiply reduce compact failure evidence outside their vector loops. Integer division stops at the first failure and writes directly into uninitialized output. Decimal arithmetic remains on its existing columnar path.

With Rust 1.97.1 and LLVM 22.1.6, optimized IR and assembly confirm that mixed-constant add, subtract, and multiply vectorize under the 16-CGU, no-LTO benchmark profile. The earlier 4.6–7.5x mixed-constant regressions were measured before the output-iterator fix in #9353 and no longer describe this branch.

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

There are no public API changes. Primitive arithmetic delegates execution to the private NumericBinary row kernel.

@connortsui20 connortsui20 changed the title ct/row fn numeric operators Execute primitive numeric operators 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 21.48%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚡ 5 improved benchmarks
❌ 45 regressed benchmarks
✅ 1954 untouched benchmarks
🆕 25 new benchmarks
⏩ 89 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation mul_i8_nonnull 167.5 µs 512.6 µs -67.32%
Simulation mul_u8_nonnull 162.1 µs 485.2 µs -66.6%
Simulation mul_u16_nonnull 266.8 µs 577 µs -53.76%
Simulation mul_i16_nonnull 278.8 µs 571 µs -51.18%
Simulation mul_i32_nullable 557.9 µs 1,062.5 µs -47.49%
Simulation mul_i32_constant 362.8 µs 672.9 µs -46.08%
Simulation add_i64_nullable 963.8 µs 1,755.2 µs -45.09%
Simulation mul_u32_nonnull 483 µs 793.8 µs -39.15%
Simulation add_i32_nonnull 481.5 µs 765.7 µs -37.11%
Simulation mul_i32_nonnull 506.6 µs 770.2 µs -34.23%
Simulation add_u32_nonnull 481.9 µs 731.6 µs -34.14%
Simulation sub_i64_constant 636.6 µs 949 µs -32.92%
Simulation add_i64_constant 636.4 µs 938.9 µs -32.21%
Simulation list_length_large 22.2 ms 30.8 ms -27.93%
Simulation list_length_medium 339.1 µs 441.1 µs -23.13%
Simulation add_i64_nonnull 912.4 µs 1,168.6 µs -21.92%
Simulation multipolygon_random_nulls 749 µs 907.2 µs -17.44%
Simulation linestrings 164.9 µs 198.8 µs -17.04%
Simulation points 163.1 µs 196.5 µs -16.99%
Simulation two_vertex_lines 280 µs 336.9 µs -16.88%
... ... ... ... ... ...

ℹ️ 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-numeric-operators (dc599ad) with develop (54e01d4)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-batch (6e5d5f3) during the generation of this report, so develop (54e01d4) 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-numeric-operators branch from ab0697a to b63ded4 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 added a commit that referenced this pull request Aug 11, 2026
## Rationale for this change

Lets indexed lane sources return borrowed or otherwise non-`Copy` items.
RowFn needs this for typed row inputs without adding a second kernel
abstraction.

- Progress towards: #9129

## What changes are included in this PR?

Removes the `Copy` bound from `IndexedSource::Item`. It also makes
`LaneZip` fields private, validates lengths once in `LaneZip::new`, and
removes the repeated assertion from its inline `len` method.

This is a prerequisite only. The first production RowFn adopter is in
#9345, so there is no meaningful RowFn performance comparison at this
layer.

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

`LaneZip` must now be constructed with `LaneZip::new` instead of tuple
syntax. The workspace has no direct field construction outside this
module.

Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch 3 times, most recently from f8670a8 to f108cdd Compare August 11, 2026 19:36
@connortsui20

Copy link
Copy Markdown
Member Author

Here are the local arithmetic 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 the primitive arithmetic 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 main results are:

  • Large per-row add, subtract, and multiply range from 2.67% faster to 4.84% slower.
  • Large mixed-constant multiply improves by 18.66–19.46%.
  • LLVM 22 does not vectorize the large mixed-constant add and subtract loops. These cases are 4.62–5.22x slower.
  • mul_i32_constant is 7.46x slower for the same LLVM 22 code-generation problem.
  • Small batches expose the fixed cost of RowFn dispatch and output construction.

A separate comparison covered the later naming and structural cleanup. All 24 RowFn matrix cases remained between 2.59% faster and 1.09% slower.

RowFn arithmetic matrix: 24 cases
Operator Rows Inputs Baseline RowFn Change
Add 128 per-row × per-row 672.2 ns 879.7 ns +30.87%
Add 128 per-row × constant 687.2 ns 1.499 µs +116.56%
Add 128 constant × per-row 739.7 ns 1.519 µs +105.35%
Add 128 per-row × nullable constant 729.7 ns 1.799 µs +146.54%
Add 32,768 per-row × per-row 7.029 µs 7.309 µs +4.84%
Add 32,768 per-row × constant 4.599 µs 22.820 µs +395.76%
Add 32,768 constant × per-row 4.619 µs 24.120 µs +421.76%
Add 32,768 per-row × nullable constant 4.609 µs 23.150 µs +402.27%
Subtract 128 per-row × per-row 667.2 ns 859.7 ns +28.85%
Subtract 128 per-row × constant 682.2 ns 1.499 µs +118.79%
Subtract 128 constant × per-row 729.7 ns 1.519 µs +109.54%
Subtract 128 per-row × nullable constant 694.7 ns 1.809 µs +160.84%
Subtract 32,768 per-row × per-row 7.149 µs 7.319 µs +3.28%
Subtract 32,768 per-row × constant 4.639 µs 22.130 µs +377.04%
Subtract 32,768 constant × per-row 4.639 µs 23.570 µs +407.87%
Subtract 32,768 per-row × nullable constant 4.649 µs 22.450 µs +382.90%
Multiply 128 per-row × per-row 754.7 ns 929.7 ns +23.19%
Multiply 128 per-row × constant 794.7 ns 1.499 µs +91.03%
Multiply 128 constant × per-row 839.7 ns 1.519 µs +81.12%
Multiply 128 per-row × nullable constant 794.7 ns 1.809 µs +126.37%
Multiply 32,768 per-row × per-row 24.790 µs 24.140 µs -2.67%
Multiply 32,768 per-row × constant 29.280 µs 23.570 µs -19.41%
Multiply 32,768 constant × per-row 29.310 µs 23.580 µs -19.46%
Multiply 32,768 per-row × nullable constant 29.280 µs 23.870 µs -18.66%
Existing arithmetic cases and controls: 28 cases
Benchmark Baseline RowFn stack Change
mul_i32_constant 3.609 µs 26.910 µs +645.64%
add_i64_constant 4.499 µs 22.780 µs +406.33%
sub_i64_constant 4.819 µs 22.260 µs +361.92%
mul_i8_nonnull 1.789 µs 1.959 µs +9.45%
mul_i16_nonnull 2.409 µs 2.599 µs +7.89%
mul_u8_nonnull 1.849 µs 1.999 µs +7.53%
mul_u16_nonnull 2.149 µs 2.319 µs +7.45%
add_i32_nonnull 3.569 µs 3.739 µs +5.04%
mul_i32_nonnull 4.099 µs 4.309 µs +4.89%
mul_u32_nonnull 3.649 µs 3.839 µs +4.40%
add_u32_nonnull 3.609 µs 3.739 µs +3.61%
add_i64_nonnull 6.459 µs 6.659 µs +3.08%
and_bool_nullable 2.019 µs 2.069 µs +2.46%
mul_i32_nullable 4.969 µs 5.049 µs +1.40%
div_i64_nonnull 44.730 µs 44.900 µs +0.34%
mul_decimal_i128_nullable 63.420 µs 63.610 µs +0.27%
lt_i64_nullable 4.709 µs 4.719 µs +0.21%
add_decimal_i128_nullable 121.200 µs 121.400 µs +0.17%
mul_decimal_i64_nonnull 16.100 µs 16.120 µs +0.12%
add_decimal_i64_nonnull 65.620 µs 65.590 µs +0.05%
div_decimal_i64_nonnull 63.960 µs 63.960 µs +0.02%
add_i64_nullable 7.449 µs 7.449 µs -0.27%
div_decimal_i128_nullable 166.600 µs 165.900 µs -0.36%
eq_i64_constant 2.719 µs 2.709 µs -0.37%
or_bool_constant 869.7 ns 859.7 ns -1.15%
mul_i64_nonnull 24.680 µs 23.970 µs -2.80%
mul_u64_nonnull 19.300 µs 18.640 µs -3.42%
div_i64_nullable not present 40.610 µs candidate only

div_i64_nullable was new in the candidate inventory, so it has no paired develop result.

@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch 2 times, most recently from b2495de to c1584a6 Compare August 12, 2026 17:53
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from c1584a6 to b722af5 Compare August 12, 2026 18:09
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from b722af5 to eea857d Compare August 12, 2026 18:46
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch 2 times, most recently from 0e8ab1d to 7693f90 Compare August 12, 2026 20:26
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch 2 times, most recently from 1dd63b9 to 9be3db4 Compare August 12, 2026 21:03
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from 413796d to 00f78ed Compare August 17, 2026 19:17
@connortsui20
connortsui20 changed the base branch from ct/row-fn-framework to ct/row-fn-batch August 17, 2026 19:18
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from 00f78ed to 803154d Compare August 17, 2026 19:43
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from 803154d to c47f0b9 Compare August 17, 2026 19:57
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from c47f0b9 to a568375 Compare August 17, 2026 20:12
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch 2 times, most recently from 0df353f to 2201917 Compare August 17, 2026 20:59
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from 2201917 to 0db5947 Compare August 17, 2026 21:11
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from 0db5947 to 73f1012 Compare August 18, 2026 15:15
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from 73f1012 to 0386a28 Compare August 18, 2026 15:31
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from 0386a28 to cf5e273 Compare August 18, 2026 18:19
@connortsui20
connortsui20 force-pushed the ct/row-fn-numeric-operators branch from cf5e273 to 71888e8 Compare August 18, 2026 19:09
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/performance A performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant