Skip to content

perf: Optimize appending out-of-line views in concat, BatchCoalescer - #11770

Open
neilconway wants to merge 3 commits into
apache:mainfrom
neilconway:neilc/view-buffer-index-shift
Open

neilconway wants to merge 3 commits into
apache:mainfrom
neilconway:neilc/view-buffer-index-shift

Conversation

@neilconway

@neilconway neilconway commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

  • N/A

Rationale for this change

When views are appended to an array that already has data buffers, the view of each out-of-line string must have its buffer index increased by the number of buffers already in the array. The obvious way to do this is to unpack the view (u128 -> ByteView), update the buffer_index field, and re-pack it. During the course of working on #11656, we found that it is significantly faster to instead update the corresponding bits in the raw view directly, via shifting and addition.

This PR applies this optimization to two additional places: GenericByteViewBuilder::append_array, which concat uses for string and binary view arrays, and InProgressByteViewArray::append_views_and_update_buffer_index, which is used by BatchCoalescer.

What changes are included in this PR?

See above. We also add a sanity-check that the output buffer count fits in 32 bits (which will always be true in practice; the previous behavior of GenericByteViewBuilder::append_array was to silently truncate the buffer count in this situation). The benchmark improvements for concat and coalesce_kernels landed separately in #11768. This PR also passes the RNG seed to the Utf8 and Dictionary(Int32, Utf8) inputs of coalesce_kernels, which previously generated the same strings for every batch.

Benchmarks

  • AMD EPYC Milan (x86)
    • coalesce_kernels, filter keeping 1% of rows
      • single_utf8view, no nulls: 3.30 ms → 3.20 ms (−3.0%)
      • single_utf8view (string_len=13..40), no nulls: 3.29 ms → 3.23 ms (−2.0%) (runs 3% apart)
      • single_binaryview, no nulls: 3.30 ms → 3.17 ms (−4.1%) (runs 6% apart)
      • mixed_utf8view (max_string_len=20), no nulls: 1.78 ms → 1.73 ms (−2.6%)
      • mixed_binaryview (max_string_len=20), no nulls: 1.86 ms → 1.81 ms (−2.9%) (runs 7% apart)
      • single_utf8view, 10% nulls: 4.93 ms → 4.80 ms (−2.8%)
      • single_utf8view (string_len=13..40), 10% nulls: 5.05 ms → 4.89 ms (−3.2%)
      • single_binaryview, 10% nulls: 4.92 ms → 4.89 ms (−0.5%)
      • mixed_utf8view (max_string_len=20), 10% nulls: 3.09 ms → 3.05 ms (−1.3%)
      • mixed_binaryview (max_string_len=20), 10% nulls: 3.08 ms → 3.06 ms (−0.4%)
    • coalesce_kernels, filter keeping 80% of rows
      • single_utf8view, no nulls: 868.1 µs → 783.3 µs (−9.8%)
      • single_utf8view (string_len=13..40), no nulls: 867.8 µs → 800.2 µs (−7.8%) (runs 4% apart)
      • single_binaryview, no nulls: 868.5 µs → 793.2 µs (−8.7%) (runs 2.9% apart)
      • mixed_utf8view (max_string_len=20), no nulls: 730.6 µs → 701.1 µs (−4.0%)
      • mixed_binaryview (max_string_len=20), no nulls: 1.50 ms → 1.50 ms (+0.3%) (copies its strings, so doesn't reach the changed code)
      • single_utf8view, 10% nulls: 1.01 ms → 922.8 µs (−8.7%)
      • single_utf8view (string_len=13..40), 10% nulls: 1.02 ms → 949.7 µs (−6.5%)
      • single_binaryview, 10% nulls: 1.02 ms → 921.9 µs (−10.0%)
      • mixed_utf8view (max_string_len=20), 10% nulls: 900.1 µs → 869.6 µs (−3.4%)
      • mixed_binaryview (max_string_len=20), 10% nulls: 895.8 µs → 873.1 µs (−2.5%)
    • coalesce_kernels, take of 80% of rows
      • single_utf8view, no nulls: 824.6 µs → 757.0 µs (−8.2%) (runs 2.8% apart)
      • single_binaryview, no nulls: 830.5 µs → 737.2 µs (−11.2%) (runs 4% apart)
      • mixed_utf8view (max_string_len=20), no nulls: 563.8 µs → 515.6 µs (−8.5%) (runs 2.4% apart)
      • mixed_binaryview (max_string_len=20), no nulls: 1.43 ms → 1.43 ms (+0.2%) (copies its strings, so doesn't reach the changed code)
      • single_utf8view, 10% nulls: 1.17 ms → 1.06 ms (−10.2%) (runs 7% apart)
      • single_binaryview, 10% nulls: 1.15 ms → 1.05 ms (−8.5%) (runs 4% apart)
      • mixed_utf8view (max_string_len=20), 10% nulls: 924.3 µs → 885.9 µs (−4.2%) (runs 3% apart)
      • mixed_binaryview (max_string_len=20), 10% nulls: 919.9 µs → 906.8 µs (−1.4%) (runs 6% apart)
    • concat of 10 string view arrays of 8192 rows
      • all_inline str_len=12, no nulls: 31.57 µs → 31.54 µs (−0.1%)
      • str_len=20, no nulls: 74.88 µs → 48.63 µs (−35.1%)
      • str_len=128, no nulls: 75.02 µs → 49.00 µs (−34.7%)
      • mixed str_len=3..20, no nulls: 73.95 µs → 48.69 µs (−34.2%)
      • all_inline str_len=12, 20% nulls: 32.44 µs → 32.39 µs (−0.2%)
      • str_len=20, 20% nulls: 76.59 µs → 50.01 µs (−34.7%)
      • str_len=128, 20% nulls: 76.39 µs → 49.99 µs (−34.6%)
      • mixed str_len=3..20, 20% nulls: 75.54 µs → 49.92 µs (−33.9%) (runs 4% apart)
  • Apple M4 Max (ARM)
    • coalesce_kernels, filter keeping 1% of rows
      • single_utf8view, no nulls: 1.62 ms → 1.51 ms (−6.9%) (runs 4% apart)
      • single_utf8view (string_len=13..40), no nulls: 1.62 ms → 1.54 ms (−5.0%) (runs 4% apart)
      • single_binaryview, no nulls: 1.57 ms → 1.48 ms (−5.7%) (runs 2.4% apart)
      • mixed_utf8view (max_string_len=20), no nulls: 1.08 ms → 1.04 ms (−3.3%)
      • mixed_binaryview (max_string_len=20), no nulls: 1.12 ms → 1.05 ms (−6.1%) (runs 5% apart)
      • single_utf8view, 10% nulls: 2.44 ms → 2.43 ms (−0.3%) (runs 2.2% apart)
      • single_utf8view (string_len=13..40), 10% nulls: 2.49 ms → 2.45 ms (−1.4%) (runs 2.5% apart)
      • single_binaryview, 10% nulls: 2.45 ms → 2.47 ms (+1.0%) (runs 6% apart)
      • mixed_utf8view (max_string_len=20), 10% nulls: 2.61 ms → 2.54 ms (−2.6%)
      • mixed_binaryview (max_string_len=20), 10% nulls: 2.58 ms → 2.53 ms (−2.2%)
    • coalesce_kernels, filter keeping 80% of rows
      • single_utf8view, no nulls: 562.9 µs → 519.8 µs (−7.7%)
      • single_utf8view (string_len=13..40), no nulls: 562.7 µs → 520.0 µs (−7.6%)
      • single_binaryview, no nulls: 562.5 µs → 520.3 µs (−7.5%)
      • mixed_utf8view (max_string_len=20), no nulls: 535.7 µs → 517.7 µs (−3.4%)
      • mixed_binaryview (max_string_len=20), no nulls: 1.10 ms → 1.11 ms (+1.7%) (copies its strings, so doesn't reach the changed code)
      • single_utf8view, 10% nulls: 618.9 µs → 578.6 µs (−6.5%)
      • single_utf8view (string_len=13..40), 10% nulls: 617.9 µs → 574.5 µs (−7.0%)
      • single_binaryview, 10% nulls: 621.6 µs → 574.5 µs (−7.6%)
      • mixed_utf8view (max_string_len=20), 10% nulls: 600.8 µs → 581.4 µs (−3.2%)
      • mixed_binaryview (max_string_len=20), 10% nulls: 602.1 µs → 581.4 µs (−3.4%)
    • coalesce_kernels, take of 80% of rows
      • single_utf8view, no nulls: 458.1 µs → 397.7 µs (−13.2%)
      • single_binaryview, no nulls: 448.5 µs → 389.3 µs (−13.2%) (runs 3.0% apart)
      • mixed_utf8view (max_string_len=20), no nulls: 311.2 µs → 290.2 µs (−6.7%)
      • mixed_binaryview (max_string_len=20), no nulls: 995.3 µs → 999.1 µs (+0.4%) (copies its strings, so doesn't reach the changed code)
      • single_utf8view, 10% nulls: 641.5 µs → 560.2 µs (−12.7%) (runs 4% apart)
      • single_binaryview, 10% nulls: 639.6 µs → 545.5 µs (−14.7%)
      • mixed_utf8view (max_string_len=20), 10% nulls: 468.9 µs → 450.5 µs (−3.9%)
      • mixed_binaryview (max_string_len=20), 10% nulls: 470.5 µs → 448.9 µs (−4.6%)
    • concat of 10 string view arrays of 8192 rows
      • all_inline str_len=12, no nulls: 15.67 µs → 15.61 µs (−0.4%)
      • str_len=20, no nulls: 31.13 µs → 27.40 µs (−12.0%)
      • str_len=128, no nulls: 31.20 µs → 27.55 µs (−11.7%)
      • mixed str_len=3..20, no nulls: 30.80 µs → 27.24 µs (−11.6%)
      • all_inline str_len=12, 20% nulls: 16.16 µs → 16.10 µs (−0.4%)
      • str_len=20, 20% nulls: 31.77 µs → 28.10 µs (−11.5%)
      • str_len=128, 20% nulls: 31.84 µs → 28.28 µs (−11.2%)
      • mixed str_len=3..20, 20% nulls: 31.33 µs → 27.92 µs (−10.9%)

Are these changes tested?

Covered by existing tests.

Are there any significant user-facing changes?

Only in a corner case: if the output buffer count exceeds u32::MAX, we now panic rather than silently truncating the count.

@neilconway neilconway changed the title perf: Optimize out-of-line views in concat, BatchCoalescer perf: Optimize appending out-of-line views in concat, BatchCoalescer Oct 21, 2026
@neilconway
neilconway force-pushed the neilc/view-buffer-index-shift branch from eae820b to 1c28b8e Compare October 23, 2026 14:54
@neilconway
neilconway marked this pull request as ready for review October 23, 2026 14:54
@github-actions github-actions Bot added arrow-core Core crates related to representing arrow data arrow-kernels Crates that transform arrow data (e.g. compute, cast) labels Oct 23, 2026
@neilconway

Copy link
Copy Markdown
Contributor Author

run benchmark coalesce_kernels
env:
BENCH_FILTER: '^(filter|take): .*view'

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: coalesce_kernels

Sharding factor: 1 (1 workers).

Comparing neilc/view-buffer-index-shift (1c28b8e) to df4dc3e (merge-base) diff

Run configuration
run benchmark coalesce_kernels
env:
  BENCH_FILTER: '^(filter|take): .*view'
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@neilconway

Copy link
Copy Markdown
Contributor Author

run benchmark concatenate_kernel
env:
BENCH_FILTER: utf8_view

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: concatenate_kernel

Sharding factor: 1 (1 workers).

Comparing neilc/view-buffer-index-shift (1c28b8e) to df4dc3e (merge-base) diff

Run configuration
run benchmark concatenate_kernel
env:
  BENCH_FILTER: utf8_view
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: concatenate_kernel

Comparing neilc/view-buffer-index-shift (1c28b8e) to df4dc3e (merge-base) diff

Run configuration
run benchmark concatenate_kernel
env:
  BENCH_FILTER: utf8_view
shards: 1
Details
group                                                      base                                   changed
-----                                                      ----                                   -------
concat utf8_view all_inline str_len=12 null_density=0      1.02     25.5±0.16µs        ? ?/sec    1.00     25.1±0.15µs        ? ?/sec
concat utf8_view all_inline str_len=12 null_density=0.2    1.01     26.3±0.29µs        ? ?/sec    1.00     26.0±0.48µs        ? ?/sec
concat utf8_view mixed str_len=3..20 null_density=0        1.18     60.2±0.22µs        ? ?/sec    1.00     51.1±0.19µs        ? ?/sec
concat utf8_view mixed str_len=3..20 null_density=0.2      1.20     62.3±0.26µs        ? ?/sec    1.00     52.0±0.20µs        ? ?/sec
concat utf8_view str_len=128 null_density=0                1.18     60.9±0.33µs        ? ?/sec    1.00     51.5±0.21µs        ? ?/sec
concat utf8_view str_len=128 null_density=0.2              1.18     62.2±0.28µs        ? ?/sec    1.00     52.9±0.21µs        ? ?/sec
concat utf8_view str_len=20 null_density=0                 1.19     61.3±0.19µs        ? ?/sec    1.00     51.4±0.25µs        ? ?/sec
concat utf8_view str_len=20 null_density=0.2               1.18     62.2±0.34µs        ? ?/sec    1.00     52.7±0.18µs        ? ?/sec

Per-runner information
concatenate_kernel — shard 1/1

Node: gk3-benchmark-cluster-nap-yar4jndv-034ff9fd-wmds

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

uname:

Linux bench-c6367887312-3796-gr6vj 6.12.105+ #1 SMP Sat Sep  5 07:54:11 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench concatenate_kernel
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
Resource Usage

base (merge-base)

Metric Value
Wall time 80.0s
Peak memory 158.0 MiB
Avg memory 90.7 MiB
CPU user 74.8s
CPU sys 0.1s
Peak spill 0 B

branch

Metric Value
Wall time 75.0s
Peak memory 130.5 MiB
Avg memory 91.0 MiB
CPU user 70.0s
CPU sys 0.0s
Peak spill 0 B

File an issue against this benchmark runner

@mbutrovich mbutrovich 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.

Thanks @neilconway! The codegen matches what we saw on #11656, and on an M5 Max with thin LTO the concat utf8_view cases with out-of-line strings are 9.5% to 11% faster, with and without code-alignment flags.

@neilconway

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @mbutrovich !

The `Utf8` and `Dictionary(Int32, Utf8)` inputs of the `coalesce`
benchmarks ignored their seed, so all 10 input batches of each held the
same strings, and only the filters and indices changed from batch to
batch. Each batch now draws its strings from its own seed, with the same
distribution of lengths, nulls and characters as before. The other
string and binary inputs already used the seed.
…lescer`

When `BatchCoalescer` keeps an input's string view data buffers instead
of copying its strings, it adds the number of buffers already in the
output to the buffer index of each view longer than 12 bytes. It
unpacked each such view into a `ByteView`, added the offset to the
`buffer_index` field, and packed the fields back into a `u128`. Now it
picks the offset or 0 from the view's length, shifts it to the position
of the buffer index, bits 64 to 95, and adds it to the whole view.

The increased index is less than the number of buffers in the output,
so the sum never carries into bit 96 as long as that number fits in 32
bits. The coalescer checked the number before adding the input's
buffers; it now checks it after, so the check covers every increased
index.

`coalesce_kernels` cases that take this path, each version run twice in
alternating order. The `mixed_binaryview` cases without nulls that keep
80% of rows copy their strings instead, and are left out.

- AMD EPYC Milan: all 26 cases are faster, by 0.4% to 11%. Filters that
  keep 80% of rows: -2.5% to -10%; `take` of 80%: -1.4% to -11%;
  filters that keep 1%: -0.4% to -4%. Strings of 13 to 39 bytes, all
  stored out of line: -2% to -7.8%.
- Apple M4 Max: 25 cases are faster, by 0.3% to 15%. One is 1% slower:
  a filter that keeps 1% of `BinaryView` rows with nulls, whose two runs
  were 6% apart. Filters that keep 80%: -3.2% to -7.7%; `take` of 80%:
  -3.9% to -15%; filters that keep 1%: -6.9% to +1%. Strings of 13 to
  39 bytes: -1.4% to -7.6%.
…yteViewBuilder::append_array`

`GenericByteViewBuilder::append_array`, which `concat` uses for string
and binary views, adds the number of data buffers already in the
builder to the buffer index of each appended view longer than 12 bytes.
It unpacked each such view into a `ByteView`, added the offset to the
`buffer_index` field, and packed the fields back into a `u128`. Now it
picks the offset or 0 from the view's length, shifts it to the position
of the buffer index, bits 64 to 95, and adds it to the whole view.

The increased index is less than the number of buffers in the builder,
so the sum never carries into bit 96 as long as that number fits in 32
bits. `append_array` truncated the number to 32 bits without checking
it; it now panics if the number doesn't fit, as the builder already
does when it adds a single buffer.

`concat` of 10 string view arrays of 8192 rows, each version run twice
in alternating order:

- AMD EPYC Milan: -34% to -35% when the arrays have out-of-line strings,
  whether all of their strings are (20 or 128 bytes) or about 40% are
  (3 to 19 bytes), with or without nulls. Arrays of inline strings take
  a path that doesn't change, and are within 0.2%.
- Apple M4 Max: -11% to -12% for the same cases. Arrays of inline
  strings are within 0.4%.
@neilconway
neilconway force-pushed the neilc/view-buffer-index-shift branch from 1c28b8e to d666b34 Compare October 23, 2026 15:49
@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: coalesce_kernels

Comparing neilc/view-buffer-index-shift (1c28b8e) to df4dc3e (merge-base) diff

Run configuration
run benchmark coalesce_kernels
env:
  BENCH_FILTER: '^(filter|take): .*view'
shards: 1
Details
group                                                                                  base                                   changed
-----                                                                                  ----                                   -------
filter: mixed_binaryview (max_string_len=128), 8192, nulls: 0, selectivity: 0.001      1.01     14.9±0.05ms        ? ?/sec    1.00     14.7±0.05ms        ? ?/sec
filter: mixed_binaryview (max_string_len=128), 8192, nulls: 0, selectivity: 0.01       1.02      2.2±0.00ms        ? ?/sec    1.00      2.2±0.01ms        ? ?/sec
filter: mixed_binaryview (max_string_len=128), 8192, nulls: 0, selectivity: 0.1        1.04      2.2±0.01ms        ? ?/sec    1.00      2.1±0.01ms        ? ?/sec
filter: mixed_binaryview (max_string_len=128), 8192, nulls: 0, selectivity: 0.8        1.01   1590.2±8.34µs        ? ?/sec    1.00  1579.7±11.06µs        ? ?/sec
filter: mixed_binaryview (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.001    1.00     24.2±0.18ms        ? ?/sec    1.00     24.2±0.14ms        ? ?/sec
filter: mixed_binaryview (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.01     1.01      4.0±0.01ms        ? ?/sec    1.00      3.9±0.01ms        ? ?/sec
filter: mixed_binaryview (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.1      1.00      2.5±0.01ms        ? ?/sec    1.01      2.5±0.03ms        ? ?/sec
filter: mixed_binaryview (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.8      1.03    655.7±0.94µs        ? ?/sec    1.00    635.4±1.41µs        ? ?/sec
filter: mixed_binaryview (max_string_len=20), 8192, nulls: 0, selectivity: 0.001       1.00     13.5±0.05ms        ? ?/sec    1.01     13.6±0.05ms        ? ?/sec
filter: mixed_binaryview (max_string_len=20), 8192, nulls: 0, selectivity: 0.01        1.02      2.1±0.00ms        ? ?/sec    1.00      2.1±0.01ms        ? ?/sec
filter: mixed_binaryview (max_string_len=20), 8192, nulls: 0, selectivity: 0.1         1.02   1305.0±4.49µs        ? ?/sec    1.00  1284.5±130.58µs        ? ?/sec
filter: mixed_binaryview (max_string_len=20), 8192, nulls: 0, selectivity: 0.8         1.00   1019.5±3.37µs        ? ?/sec    1.00   1021.2±3.14µs        ? ?/sec
filter: mixed_binaryview (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.001     1.00     22.7±0.16ms        ? ?/sec    1.01     23.0±0.12ms        ? ?/sec
filter: mixed_binaryview (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.01      1.00      3.9±0.01ms        ? ?/sec    1.00      3.8±0.02ms        ? ?/sec
filter: mixed_binaryview (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.1       1.00   1705.4±4.43µs        ? ?/sec    1.00   1705.5±3.58µs        ? ?/sec
filter: mixed_binaryview (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.8       1.05    658.1±1.05µs        ? ?/sec    1.00    628.6±1.91µs        ? ?/sec
filter: mixed_binaryview (max_string_len=8), 8192, nulls: 0, selectivity: 0.001        1.00      8.5±0.03ms        ? ?/sec    1.00      8.4±0.03ms        ? ?/sec
filter: mixed_binaryview (max_string_len=8), 8192, nulls: 0, selectivity: 0.01         1.00   1793.3±3.64µs        ? ?/sec    1.00   1796.5±2.11µs        ? ?/sec
filter: mixed_binaryview (max_string_len=8), 8192, nulls: 0, selectivity: 0.1          1.03    855.5±3.00µs        ? ?/sec    1.00   829.2±10.25µs        ? ?/sec
filter: mixed_binaryview (max_string_len=8), 8192, nulls: 0, selectivity: 0.8          1.00    409.7±0.48µs        ? ?/sec    1.02    417.4±0.66µs        ? ?/sec
filter: mixed_binaryview (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.001      1.00     18.5±0.09ms        ? ?/sec    1.01     18.7±0.11ms        ? ?/sec
filter: mixed_binaryview (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.01       1.00      3.7±0.01ms        ? ?/sec    1.00      3.7±0.01ms        ? ?/sec
filter: mixed_binaryview (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.1        1.00   1301.4±2.14µs        ? ?/sec    1.00   1297.1±2.65µs        ? ?/sec
filter: mixed_binaryview (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.8        1.00    528.5±0.56µs        ? ?/sec    1.02    537.4±1.88µs        ? ?/sec
filter: mixed_utf8view (max_string_len=128), 8192, nulls: 0, selectivity: 0.001        1.00     14.7±0.04ms        ? ?/sec    1.00     14.7±0.07ms        ? ?/sec
filter: mixed_utf8view (max_string_len=128), 8192, nulls: 0, selectivity: 0.01         1.02      2.2±0.00ms        ? ?/sec    1.00      2.2±0.01ms        ? ?/sec
filter: mixed_utf8view (max_string_len=128), 8192, nulls: 0, selectivity: 0.1          1.05      2.2±0.01ms        ? ?/sec    1.00      2.1±0.01ms        ? ?/sec
filter: mixed_utf8view (max_string_len=128), 8192, nulls: 0, selectivity: 0.8          1.00   1547.3±7.70µs        ? ?/sec    1.01  1555.3±14.93µs        ? ?/sec
filter: mixed_utf8view (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.001      1.00     23.8±0.14ms        ? ?/sec    1.01     24.1±0.16ms        ? ?/sec
filter: mixed_utf8view (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.01       1.00      4.0±0.01ms        ? ?/sec    1.00      4.0±0.01ms        ? ?/sec
filter: mixed_utf8view (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.1        1.00      2.5±0.01ms        ? ?/sec    1.00      2.5±0.01ms        ? ?/sec
filter: mixed_utf8view (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.8        1.06    662.4±1.42µs        ? ?/sec    1.00    627.5±1.12µs        ? ?/sec
filter: mixed_utf8view (max_string_len=20), 8192, nulls: 0, selectivity: 0.001         1.00     13.1±0.06ms        ? ?/sec    1.02     13.3±0.04ms        ? ?/sec
filter: mixed_utf8view (max_string_len=20), 8192, nulls: 0, selectivity: 0.01          1.01      2.1±0.00ms        ? ?/sec    1.00      2.0±0.01ms        ? ?/sec
filter: mixed_utf8view (max_string_len=20), 8192, nulls: 0, selectivity: 0.1           1.05   1287.9±5.50µs        ? ?/sec    1.00   1225.2±5.73µs        ? ?/sec
filter: mixed_utf8view (max_string_len=20), 8192, nulls: 0, selectivity: 0.8           1.06    534.6±0.93µs        ? ?/sec    1.00    505.2±1.15µs        ? ?/sec
filter: mixed_utf8view (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.001       1.00     22.7±0.15ms        ? ?/sec    1.01     23.0±0.15ms        ? ?/sec
filter: mixed_utf8view (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.01        1.00      3.8±0.01ms        ? ?/sec    1.00      3.8±0.01ms        ? ?/sec
filter: mixed_utf8view (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.1         1.00   1663.5±4.05µs        ? ?/sec    1.01   1675.0±4.17µs        ? ?/sec
filter: mixed_utf8view (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.8         1.02    645.4±1.30µs        ? ?/sec    1.00    633.2±1.37µs        ? ?/sec
filter: mixed_utf8view (max_string_len=8), 8192, nulls: 0, selectivity: 0.001          1.00      8.4±0.03ms        ? ?/sec    1.01      8.5±0.04ms        ? ?/sec
filter: mixed_utf8view (max_string_len=8), 8192, nulls: 0, selectivity: 0.01           1.00   1786.9±2.14µs        ? ?/sec    1.01   1797.9±2.85µs        ? ?/sec
filter: mixed_utf8view (max_string_len=8), 8192, nulls: 0, selectivity: 0.1            1.05    846.2±1.75µs        ? ?/sec    1.00    803.9±3.00µs        ? ?/sec
filter: mixed_utf8view (max_string_len=8), 8192, nulls: 0, selectivity: 0.8            1.00    409.7±0.56µs        ? ?/sec    1.02    417.2±1.26µs        ? ?/sec
filter: mixed_utf8view (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.001        1.00     19.1±0.15ms        ? ?/sec    1.01     19.2±0.11ms        ? ?/sec
filter: mixed_utf8view (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.01         1.00      3.7±0.01ms        ? ?/sec    1.01      3.7±0.01ms        ? ?/sec
filter: mixed_utf8view (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.1          1.01   1312.9±2.50µs        ? ?/sec    1.00   1301.3±4.80µs        ? ?/sec
filter: mixed_utf8view (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.8          1.00    525.1±0.75µs        ? ?/sec    1.02    537.6±1.28µs        ? ?/sec
filter: single_binaryview (max_string_len=8), 8192, nulls: 0, selectivity: 0.001       1.01     20.3±0.13ms        ? ?/sec    1.00     20.2±0.09ms        ? ?/sec
filter: single_binaryview (max_string_len=8), 8192, nulls: 0, selectivity: 0.01        1.00  1960.6±10.20µs        ? ?/sec    1.00   1968.5±4.35µs        ? ?/sec
filter: single_binaryview (max_string_len=8), 8192, nulls: 0, selectivity: 0.1         1.09    751.4±1.56µs        ? ?/sec    1.00    686.4±2.76µs        ? ?/sec
filter: single_binaryview (max_string_len=8), 8192, nulls: 0, selectivity: 0.8         1.03    425.5±0.79µs        ? ?/sec    1.00    414.8±0.64µs        ? ?/sec
filter: single_binaryview (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.001     1.00     30.7±0.10ms        ? ?/sec    1.01     31.1±0.13ms        ? ?/sec
filter: single_binaryview (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.01      1.00      3.3±0.02ms        ? ?/sec    1.03      3.4±0.01ms        ? ?/sec
filter: single_binaryview (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.1       1.06   1147.7±1.88µs        ? ?/sec    1.00   1078.0±2.99µs        ? ?/sec
filter: single_binaryview (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.8       1.01    511.0±0.74µs        ? ?/sec    1.00    508.4±0.89µs        ? ?/sec
filter: single_binaryview, 8192, nulls: 0, selectivity: 0.001                          1.00     32.9±0.12ms        ? ?/sec    1.01     33.3±0.08ms        ? ?/sec
filter: single_binaryview, 8192, nulls: 0, selectivity: 0.01                           1.02      3.4±0.01ms        ? ?/sec    1.00      3.3±0.01ms        ? ?/sec
filter: single_binaryview, 8192, nulls: 0, selectivity: 0.1                            1.03      2.0±0.00ms        ? ?/sec    1.00   1941.1±5.85µs        ? ?/sec
filter: single_binaryview, 8192, nulls: 0, selectivity: 0.8                            1.13    744.3±1.15µs        ? ?/sec    1.00    656.2±0.73µs        ? ?/sec
filter: single_binaryview, 8192, nulls: 0.1, selectivity: 0.001                        1.00     44.9±0.09ms        ? ?/sec    1.00     44.9±0.19ms        ? ?/sec
filter: single_binaryview, 8192, nulls: 0.1, selectivity: 0.01                         1.02      4.7±0.02ms        ? ?/sec    1.00      4.6±0.02ms        ? ?/sec
filter: single_binaryview, 8192, nulls: 0.1, selectivity: 0.1                          1.00      2.3±0.00ms        ? ?/sec    1.00      2.3±0.01ms        ? ?/sec
filter: single_binaryview, 8192, nulls: 0.1, selectivity: 0.8                          1.10    829.9±1.16µs        ? ?/sec    1.00    753.0±1.36µs        ? ?/sec
filter: single_utf8view (max_string_len=8), 8192, nulls: 0, selectivity: 0.001         1.00     20.2±0.12ms        ? ?/sec    1.00     20.2±0.10ms        ? ?/sec
filter: single_utf8view (max_string_len=8), 8192, nulls: 0, selectivity: 0.01          1.00   1954.4±6.65µs        ? ?/sec    1.01   1967.6±7.65µs        ? ?/sec
filter: single_utf8view (max_string_len=8), 8192, nulls: 0, selectivity: 0.1           1.07    732.7±2.02µs        ? ?/sec    1.00    683.2±2.99µs        ? ?/sec
filter: single_utf8view (max_string_len=8), 8192, nulls: 0, selectivity: 0.8           1.01    422.8±0.65µs        ? ?/sec    1.00    417.2±0.88µs        ? ?/sec
filter: single_utf8view (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.001       1.00     32.0±0.15ms        ? ?/sec    1.01     32.3±0.12ms        ? ?/sec
filter: single_utf8view (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.01        1.00      3.3±0.02ms        ? ?/sec    1.04      3.4±0.02ms        ? ?/sec
filter: single_utf8view (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.1         1.02   1128.9±2.39µs        ? ?/sec    1.00   1105.4±3.10µs        ? ?/sec
filter: single_utf8view (max_string_len=8), 8192, nulls: 0.1, selectivity: 0.8         1.00    507.9±0.75µs        ? ?/sec    1.02    518.7±1.02µs        ? ?/sec
filter: single_utf8view (string_len=13..40), 8192, nulls: 0, selectivity: 0.001        1.00     34.1±0.10ms        ? ?/sec    1.00     34.2±0.08ms        ? ?/sec
filter: single_utf8view (string_len=13..40), 8192, nulls: 0, selectivity: 0.01         1.03      3.5±0.02ms        ? ?/sec    1.00      3.4±0.01ms        ? ?/sec
filter: single_utf8view (string_len=13..40), 8192, nulls: 0, selectivity: 0.1          1.03      2.9±0.01ms        ? ?/sec    1.00      2.8±0.01ms        ? ?/sec
filter: single_utf8view (string_len=13..40), 8192, nulls: 0, selectivity: 0.8          1.12    743.5±0.84µs        ? ?/sec    1.00    662.1±0.63µs        ? ?/sec
filter: single_utf8view (string_len=13..40), 8192, nulls: 0.1, selectivity: 0.001      1.00     45.8±0.12ms        ? ?/sec    1.00     45.9±0.19ms        ? ?/sec
filter: single_utf8view (string_len=13..40), 8192, nulls: 0.1, selectivity: 0.01       1.00      4.8±0.02ms        ? ?/sec    1.01      4.8±0.03ms        ? ?/sec
filter: single_utf8view (string_len=13..40), 8192, nulls: 0.1, selectivity: 0.1        1.00      3.1±0.01ms        ? ?/sec    1.00      3.1±0.01ms        ? ?/sec
filter: single_utf8view (string_len=13..40), 8192, nulls: 0.1, selectivity: 0.8        1.10    827.2±0.69µs        ? ?/sec    1.00    750.6±1.41µs        ? ?/sec
filter: single_utf8view, 8192, nulls: 0, selectivity: 0.001                            1.00     32.6±0.09ms        ? ?/sec    1.01     32.8±0.08ms        ? ?/sec
filter: single_utf8view, 8192, nulls: 0, selectivity: 0.01                             1.03      3.4±0.02ms        ? ?/sec    1.00      3.3±0.01ms        ? ?/sec
filter: single_utf8view, 8192, nulls: 0, selectivity: 0.1                              1.02   1979.1±4.58µs        ? ?/sec    1.00   1938.3±4.11µs        ? ?/sec
filter: single_utf8view, 8192, nulls: 0, selectivity: 0.8                              1.13    742.2±0.72µs        ? ?/sec    1.00    654.7±0.71µs        ? ?/sec
filter: single_utf8view, 8192, nulls: 0.1, selectivity: 0.001                          1.01     44.1±0.12ms        ? ?/sec    1.00     43.8±0.12ms        ? ?/sec
filter: single_utf8view, 8192, nulls: 0.1, selectivity: 0.01                           1.00      4.7±0.02ms        ? ?/sec    1.00      4.7±0.02ms        ? ?/sec
filter: single_utf8view, 8192, nulls: 0.1, selectivity: 0.1                            1.00      2.2±0.00ms        ? ?/sec    1.00      2.2±0.00ms        ? ?/sec
filter: single_utf8view, 8192, nulls: 0.1, selectivity: 0.8                            1.10    823.3±0.85µs        ? ?/sec    1.00    750.2±1.20µs        ? ?/sec
take: mixed_binaryview (max_string_len=128), 8192, nulls: 0, selectivity: 0.001        1.01     14.6±0.09ms        ? ?/sec    1.00     14.5±0.09ms        ? ?/sec
take: mixed_binaryview (max_string_len=128), 8192, nulls: 0, selectivity: 0.01         1.00      3.3±0.01ms        ? ?/sec    1.00      3.3±0.03ms        ? ?/sec
take: mixed_binaryview (max_string_len=128), 8192, nulls: 0, selectivity: 0.1          1.00      2.7±0.01ms        ? ?/sec    1.00      2.7±0.02ms        ? ?/sec
take: mixed_binaryview (max_string_len=128), 8192, nulls: 0, selectivity: 0.8          1.06      2.0±0.41ms        ? ?/sec    1.00  1920.6±11.26µs        ? ?/sec
take: mixed_binaryview (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.001      1.00     21.3±0.07ms        ? ?/sec    1.00     21.4±0.06ms        ? ?/sec
take: mixed_binaryview (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.01       1.00      4.4±0.02ms        ? ?/sec    1.01      4.4±0.02ms        ? ?/sec
take: mixed_binaryview (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.1        1.01      2.9±0.02ms        ? ?/sec    1.00      2.9±0.02ms        ? ?/sec
take: mixed_binaryview (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.8        1.04    856.8±0.78µs        ? ?/sec    1.00    820.9±1.23µs        ? ?/sec
take: mixed_binaryview (max_string_len=20), 8192, nulls: 0, selectivity: 0.001         1.00     13.8±0.06ms        ? ?/sec    1.00     13.9±0.08ms        ? ?/sec
take: mixed_binaryview (max_string_len=20), 8192, nulls: 0, selectivity: 0.01          1.00      2.3±0.01ms        ? ?/sec    1.00      2.3±0.03ms        ? ?/sec
take: mixed_binaryview (max_string_len=20), 8192, nulls: 0, selectivity: 0.1           1.01   1619.8±3.03µs        ? ?/sec    1.00  1610.5±25.68µs        ? ?/sec
take: mixed_binaryview (max_string_len=20), 8192, nulls: 0, selectivity: 0.8           1.00   1100.0±4.58µs        ? ?/sec    1.00   1101.8±4.52µs        ? ?/sec
take: mixed_binaryview (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.001       1.00     20.5±0.09ms        ? ?/sec    1.00     20.5±0.07ms        ? ?/sec
take: mixed_binaryview (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.01        1.00      3.5±0.02ms        ? ?/sec    1.01      3.5±0.02ms        ? ?/sec
take: mixed_binaryview (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.1         1.02   1954.4±9.54µs        ? ?/sec    1.00   1920.5±2.99µs        ? ?/sec
take: mixed_binaryview (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.8         1.05    867.6±1.65µs        ? ?/sec    1.00    825.0±1.36µs        ? ?/sec
take: mixed_utf8view (max_string_len=128), 8192, nulls: 0, selectivity: 0.001          1.00     14.3±0.10ms        ? ?/sec    1.03     14.7±0.15ms        ? ?/sec
take: mixed_utf8view (max_string_len=128), 8192, nulls: 0, selectivity: 0.01           1.00      3.3±0.01ms        ? ?/sec    1.00      3.3±0.03ms        ? ?/sec
take: mixed_utf8view (max_string_len=128), 8192, nulls: 0, selectivity: 0.1            1.01      2.7±0.01ms        ? ?/sec    1.00      2.6±0.02ms        ? ?/sec
take: mixed_utf8view (max_string_len=128), 8192, nulls: 0, selectivity: 0.8            1.00   1915.6±7.41µs        ? ?/sec    1.00  1914.7±10.80µs        ? ?/sec
take: mixed_utf8view (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.001        1.00     21.2±0.14ms        ? ?/sec    1.01     21.5±0.17ms        ? ?/sec
take: mixed_utf8view (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.01         1.00      4.4±0.02ms        ? ?/sec    1.03      4.5±0.04ms        ? ?/sec
take: mixed_utf8view (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.1          1.00      2.9±0.02ms        ? ?/sec    1.00      2.9±0.02ms        ? ?/sec
take: mixed_utf8view (max_string_len=128), 8192, nulls: 0.1, selectivity: 0.8          1.05    854.4±1.85µs        ? ?/sec    1.00    816.6±1.30µs        ? ?/sec
take: mixed_utf8view (max_string_len=20), 8192, nulls: 0, selectivity: 0.001           1.00     13.6±0.07ms        ? ?/sec    1.01     13.8±0.16ms        ? ?/sec
take: mixed_utf8view (max_string_len=20), 8192, nulls: 0, selectivity: 0.01            1.00      2.3±0.02ms        ? ?/sec    1.00      2.3±0.03ms        ? ?/sec
take: mixed_utf8view (max_string_len=20), 8192, nulls: 0, selectivity: 0.1             1.01  1558.9±10.40µs        ? ?/sec    1.00   1544.3±7.48µs        ? ?/sec
take: mixed_utf8view (max_string_len=20), 8192, nulls: 0, selectivity: 0.8             1.08    590.5±1.06µs        ? ?/sec    1.00    547.2±1.14µs        ? ?/sec
take: mixed_utf8view (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.001         1.00     20.5±0.15ms        ? ?/sec    1.02     20.8±0.19ms        ? ?/sec
take: mixed_utf8view (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.01          1.00      3.5±0.02ms        ? ?/sec    1.00      3.5±0.03ms        ? ?/sec
take: mixed_utf8view (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.1           1.02   1891.9±6.27µs        ? ?/sec    1.00   1860.0±6.09µs        ? ?/sec
take: mixed_utf8view (max_string_len=20), 8192, nulls: 0.1, selectivity: 0.8           1.03    855.4±0.97µs        ? ?/sec    1.00    830.1±1.44µs        ? ?/sec
take: single_binaryview, 8192, nulls: 0, selectivity: 0.001                            1.02     16.2±0.43ms        ? ?/sec    1.00     15.8±0.19ms        ? ?/sec
take: single_binaryview, 8192, nulls: 0, selectivity: 0.01                             1.03      3.2±0.05ms        ? ?/sec    1.00      3.1±0.01ms        ? ?/sec
take: single_binaryview, 8192, nulls: 0, selectivity: 0.1                              1.02      3.3±0.01ms        ? ?/sec    1.00      3.2±0.02ms        ? ?/sec
take: single_binaryview, 8192, nulls: 0, selectivity: 0.8                              1.11    886.8±2.02µs        ? ?/sec    1.00    795.9±4.75µs        ? ?/sec
take: single_binaryview, 8192, nulls: 0.1, selectivity: 0.001                          1.02     22.2±0.31ms        ? ?/sec    1.00     21.9±0.08ms        ? ?/sec
take: single_binaryview, 8192, nulls: 0.1, selectivity: 0.01                           1.00      4.3±0.06ms        ? ?/sec    1.00      4.3±0.02ms        ? ?/sec
take: single_binaryview, 8192, nulls: 0.1, selectivity: 0.1                            1.01      3.5±0.02ms        ? ?/sec    1.00      3.5±0.01ms        ? ?/sec
take: single_binaryview, 8192, nulls: 0.1, selectivity: 0.8                            1.10   1106.9±2.50µs        ? ?/sec    1.00   1010.0±1.58µs        ? ?/sec
take: single_utf8view, 8192, nulls: 0, selectivity: 0.001                              1.02     16.1±0.27ms        ? ?/sec    1.00     15.9±0.10ms        ? ?/sec
take: single_utf8view, 8192, nulls: 0, selectivity: 0.01                               1.00      3.1±0.02ms        ? ?/sec    1.00      3.1±0.02ms        ? ?/sec
take: single_utf8view, 8192, nulls: 0, selectivity: 0.1                                1.02      3.3±0.01ms        ? ?/sec    1.00      3.2±0.02ms        ? ?/sec
take: single_utf8view, 8192, nulls: 0, selectivity: 0.8                                1.13    888.8±0.83µs        ? ?/sec    1.00    783.2±3.36µs        ? ?/sec
take: single_utf8view, 8192, nulls: 0.1, selectivity: 0.001                            1.00     21.7±0.23ms        ? ?/sec    1.02     22.1±0.12ms        ? ?/sec
take: single_utf8view, 8192, nulls: 0.1, selectivity: 0.01                             1.00      4.2±0.02ms        ? ?/sec    1.00      4.2±0.02ms        ? ?/sec
take: single_utf8view, 8192, nulls: 0.1, selectivity: 0.1                              1.01      3.5±0.01ms        ? ?/sec    1.00      3.4±0.01ms        ? ?/sec
take: single_utf8view, 8192, nulls: 0.1, selectivity: 0.8                              1.10  1109.9±48.64µs        ? ?/sec    1.00   1009.9±1.41µs        ? ?/sec

Per-runner information
coalesce_kernels — shard 1/1

Node: gk3-benchmark-cluster-nap-144p8rlm-f3485326-9ndp

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

uname:

Linux bench-c6367883948-3795-42gh9 6.12.105+ #1 SMP Sat Sep  5 07:54:11 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench coalesce_kernels
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
Resource Usage

base (merge-base)

Metric Value
Wall time 1470.3s
Peak memory 29.6 MiB
Avg memory 17.1 MiB
CPU user 1464.0s
CPU sys 0.4s
Peak spill 0 B

branch

Metric Value
Wall time 1475.3s
Peak memory 26.8 MiB
Avg memory 18.0 MiB
CPU user 1468.4s
CPU sys 0.3s
Peak spill 0 B

File an issue against this benchmark runner

@neilconway

Copy link
Copy Markdown
Contributor Author

@Rich-T-kid Any interest in reviewing?

@Rich-T-kid

Copy link
Copy Markdown
Contributor

@Rich-T-kid Any interest in reviewing?

will take a look today

@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.

turns out I took a brief glance at this before and forgot to submit the review

Comment on lines +227 to +241
///
/// # Panics
///
/// Panics if the builder would hold more than `u32::MAX` data buffers
pub fn append_array(&mut self, array: &GenericByteViewArray<T>) {
self.flush_in_progress();
// keep original views if this array is the first to be added or if there are no data buffers (all inline views)
let keep_views = self.completed.is_empty() || array.data_buffers().is_empty();
let starting_buffer = self.completed.len() as u32;

self.completed.extend(array.data_buffers().iter().cloned());
assert!(
u32::try_from(self.completed.len()).is_ok(),
"Too many blocks"
);

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.

before this assertion what happened if the builder overflowed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

On an overflow, the behavior before this PR was to panic in debug mode. In release mode, the buffer index would wrap and point at the wrong buffer.

@Rich-T-kid
Rich-T-kid self-requested a review October 26, 2026 02:49

@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.

this is quite a cool find, thanks @neilconway.

I am not sure if this qualifies as a breaking change. the API doesn't change but programs will behave very different with this change.

not sure if we need to wait for the next major release for this. cc @alamb

Comment thread arrow/benches/coalesce_kernels.rs
Comment thread arrow-select/src/coalesce/byte_view.rs
Comment on lines +227 to +230
///
/// # Panics
///
/// Panics if the builder would hold more than `u32::MAX` data buffers

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.

🤔 this makes sense to do but it is a breaking change right? code the previously worked (produced incorrect results) ran but now this will cause a panic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't think this is a breaking change. Code that produces incorrect results should not be considered "code that previously worked" -- if that was the definition of a breaking change, many straightforward bugfixes would not be allowed in minor releases.

Additional considerations:

  • In debug builds, the previous coding resulted in a panic anyway, so there is no change in behavior.
  • In release builds, the previous behavior is actually worse than just incorrect results: buffer_index points at one buffer but the view's length and offset were validated against a different buffer. Reader methods like GenericByteViewArray::value(k) do an unchecked read somewhere off into heap memory, resulting in undefined behavior.
  • Overflow requires an array with u32::MAX data buffers, which is extremely unlikely to occur in practice.

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.

Code that produces incorrect results should not be considered "code that previously worked" -- if that was the definition of a breaking change, many straightforward bugfixes would not be allowed in minor releases.

good point.

@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.

makes sense to me, thanks @neilconway & @mbutrovich for the review.

This branch has not been deployed

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

Labels

arrow-core Core crates related to representing arrow data arrow-kernels Crates that transform arrow data (e.g. compute, cast)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants