Skip to content

Use Vec for primitive array unary operations - #10783

Merged
Jefffrey merged 1 commit into
apache:mainfrom
kowanietz:perf/primitive-array-vec
Aug 24, 2026
Merged

Use Vec for primitive array unary operations#10783
Jefffrey merged 1 commit into
apache:mainfrom
kowanietz:perf/primitive-array-vec

Conversation

@kowanietz

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

Replacing BufferBuilder with Vec improves the performenace of primitive array unary operations.

What changes are included in this PR?

Replaces the BufferBuilder<...> usages in PrimitiveArray::try_unary and PrimitiveArray::unary_opt with Vecs.

Also adds benchmarks for both operations with and without input nulls

Are these changes tested?

All tests pass:

  • cargo fmt --all -- --check
  • cargo clippy -p arrow-array --all-targets --all-features --no-deps -- -D warnings
  • cargo test -p arrow-array --all-features
  • cargo bench -p arrow-array --bench primitive_array -- --test

Local benchmark results for 65,536 Int32 values:

Benchmark Before After Change
try_unary, no input nulls 10.600 µs 8.865 µs 16.4% faster
try_unary, 20% input nulls 54.486 µs 54.623 µs no clear change
unary_opt, no input nulls 48.641 µs 49.630 µs no clear change
unary_opt, 20% input nulls 75.155 µs 75.903 µs no clear change

I currently only have a MacBook available so benching this on Linux would probably make sense.

Are there any user-facing changes?

No.

@github-actions github-actions Bot added arrow Changes to the arrow crate arrow-array labels Aug 21, 2026
@kowanietz

kowanietz commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

run benchmark primitive_array

@adriangbot

Copy link
Copy Markdown

@kowanietz

Copy link
Copy Markdown
Contributor Author

Well, that's unfortunate.

Btw, in case the benchmark I added is out of scope, I'll remove it or move it to another PR :)

@Rich-T-kid

Copy link
Copy Markdown
Contributor

run benchmark primitive_array

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c5374780982-1852-vcr25 6.12.85+ #1 SMP Sat Jun 27 09:31:30 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing perf/primitive-array-vec (52b4cdd) to c837ee8 (merge-base) diff

Run configuration
run benchmark primitive_array

BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental,object_store --bench primitive_array
Results will be posted here when complete


File an issue against this benchmark runner

@Rich-T-kid Rich-T-kid left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that's unfortunate.

Btw, in case the benchmark I added is out of scope, I'll remove it or move it to another PR :)

@kowanietz yea you'd need to add the benchmarks in a separate PR to use the benchmarks bot to compare the results. I dont think thats actually needed for this PR, see @/alamb comment here apache/datafusion#24071 (comment)

LGTM

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing perf/primitive-array-vec (52b4cdd) to c837ee8 (merge-base) diff

Run configuration
run benchmark primitive_array
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

New benchmark — branch-only results (no baseline comparison)

Details

group                                                perf_primitive-array-vec
-----                                                ------------------------
primitive_array_unary/try_unary/20pct_input_nulls    1.00     43.0±0.05µs        ? ?/sec
primitive_array_unary/try_unary/no_input_nulls       1.00      5.0±0.01µs        ? ?/sec
primitive_array_unary/unary_opt/20pct_input_nulls    1.00     48.6±0.28µs        ? ?/sec
primitive_array_unary/unary_opt/no_input_nulls       1.00     39.3±0.14µs        ? ?/sec

Resource Usage

branch

Metric Value
Wall time 45.0s
Peak memory 10.0 MiB
Avg memory 6.1 MiB
CPU user 39.9s
CPU sys 0.0s
Peak spill 0 B

File an issue against this benchmark runner

@Jefffrey Jefffrey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matches my bench results locally too

primitive_array_unary/try_unary/no_input_nulls
                        time:   [4.4402 µs 4.4502 µs 4.4598 µs]
+                       change: [−15.956% −15.699% −15.431%] (p = 0.00 < 0.05)
+                       Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  1 (1.00%) low severe
  1 (1.00%) low mild
  3 (3.00%) high mild
primitive_array_unary/unary_opt/no_input_nulls
                        time:   [25.532 µs 25.647 µs 25.761 µs]
-                       change: [+1.8110% +2.1490% +2.4997%] (p = 0.00 < 0.05)
-                       Performance has regressed.
Found 15 outliers among 100 measurements (15.00%)
  12 (12.00%) high mild
  3 (3.00%) high severe
primitive_array_unary/try_unary/20pct_input_nulls
                        time:   [27.961 µs 27.990 µs 28.021 µs]
+                       change: [−5.3402% −5.0562% −4.7822%] (p = 0.00 < 0.05)
+                       Performance has improved.
Found 11 outliers among 100 measurements (11.00%)
  3 (3.00%) low severe
  4 (4.00%) low mild
  1 (1.00%) high mild
  3 (3.00%) high severe
primitive_array_unary/unary_opt/20pct_input_nulls
                        time:   [38.286 µs 38.346 µs 38.414 µs]
                        change: [−1.6937% −1.1508% −0.6379%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 15 outliers among 100 measurements (15.00%)
  2 (2.00%) low mild
  13 (13.00%) high severe
  • 1st one has improvement, other 3 probably just noise

@Jefffrey
Jefffrey merged commit 46540d9 into apache:main Aug 24, 2026
35 checks passed
@Jefffrey

Copy link
Copy Markdown
Contributor

thanks @kowanietz & @Rich-T-kid

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

Labels

arrow Changes to the arrow crate arrow-array performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants