Skip to content

Optimize delta binary decoder in the case where bitwidth=0#9477

Draft
etseidl wants to merge 12 commits intoapache:mainfrom
etseidl:delta_binary_bit_zero
Draft

Optimize delta binary decoder in the case where bitwidth=0#9477
etseidl wants to merge 12 commits intoapache:mainfrom
etseidl:delta_binary_bit_zero

Conversation

@etseidl
Copy link
Contributor

@etseidl etseidl commented Feb 25, 2026

Which issue does this PR close?

Rationale for this change

Explore if we can achieve the speedups seen in arrow-cpp (apache/arrow#49296).

What changes are included in this PR?

Adds special cases to the delta binary packed decoder when bitwidth for a miniblock is 0. The optimization avoids relying on previous values to decode current ones.

Are these changes tested?

Yes, tests have been added, as well as new benchmarks.

Are there any user-facing changes?

No

@github-actions github-actions bot added the parquet Changes to the parquet crate label Feb 25, 2026
@etseidl
Copy link
Contributor Author

etseidl commented Feb 25, 2026

Not seeing the huge improvement from arrow-cpp, but still a nice speedup, and it doesn't seem to be impacting cases where the optimization can't be used.

New benchmarks on my workstation (x86 i7-12700K) comparing main (no_opt) to this branch (opt)

group                                                                                no_opt                                 opt
-----                                                                                ------                                 ---
arrow_array_reader/INT32/Decimal128Array/binary packed increasing value              1.18     45.9±0.62µs        ? ?/sec    1.00     39.0±0.40µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed single value                  1.21     45.7±0.22µs        ? ?/sec    1.00     37.9±0.77µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed increasing value              1.18     48.2±0.50µs        ? ?/sec    1.00     40.7±0.65µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed single value                  1.19     48.1±0.19µs        ? ?/sec    1.00     40.5±0.24µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed increasing value                         1.24     38.0±1.08µs        ? ?/sec    1.00     30.7±0.18µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed single value                             1.26     37.1±0.23µs        ? ?/sec    1.00     29.4±0.12µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed increasing value                         1.23     32.6±0.46µs        ? ?/sec    1.00     26.6±0.23µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed single value                             1.28     32.5±0.19µs        ? ?/sec    1.00     25.3±0.38µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed increasing value                         1.21     35.2±0.15µs        ? ?/sec    1.00     29.0±0.12µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed single value                             1.21     35.2±0.36µs        ? ?/sec    1.00     29.1±0.21µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed increasing value                          1.20     37.5±0.25µs        ? ?/sec    1.00     31.3±0.26µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed single value                              1.27     37.9±0.59µs        ? ?/sec    1.00     30.0±0.18µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed increasing value                        1.22     37.4±0.53µs        ? ?/sec    1.00     30.6±0.10µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed single value                            1.25     37.0±0.16µs        ? ?/sec    1.00     29.6±0.19µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed increasing value                        1.24     33.6±0.18µs        ? ?/sec    1.00     27.0±0.14µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed single value                            1.30     33.5±0.18µs        ? ?/sec    1.00     25.9±0.16µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed increasing value                        1.22     35.3±0.13µs        ? ?/sec    1.00     28.9±0.20µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed single value                            1.21     35.3±0.14µs        ? ?/sec    1.00     29.3±0.39µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed increasing value                         1.19     37.4±0.25µs        ? ?/sec    1.00     31.4±0.17µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed single value                             1.23     37.4±0.19µs        ? ?/sec    1.00     30.3±0.45µs        ? ?/sec

And the rest of the binary packed benches

Details
group                                                                                no_opt                                 opt
-----                                                                                ------                                 ---
arrow_array_reader/INT32/Decimal128Array/binary packed skip, mandatory, no NULLs     1.01     50.9±0.29µs        ? ?/sec    1.00     50.3±0.29µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed skip, optional, half NULLs    1.01     59.7±0.78µs        ? ?/sec    1.00     59.4±0.82µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed skip, optional, no NULLs      1.00     51.8±0.22µs        ? ?/sec    1.00     51.7±0.21µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed, mandatory, no NULLs          1.01     73.9±0.50µs        ? ?/sec    1.00     73.4±0.29µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed, optional, half NULLs         1.02    102.4±2.40µs        ? ?/sec    1.00    100.8±1.01µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed, optional, no NULLs           1.00     75.7±0.35µs        ? ?/sec    1.00     75.8±0.36µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed skip, mandatory, no NULLs     1.02     53.4±0.57µs        ? ?/sec    1.00     52.4±0.24µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed skip, optional, half NULLs    1.00     61.2±0.26µs        ? ?/sec    1.00     61.5±0.39µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed skip, optional, no NULLs      1.00     53.7±0.28µs        ? ?/sec    1.00     53.8±0.32µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed, mandatory, no NULLs          1.00     79.1±0.86µs        ? ?/sec    1.00     79.0±0.50µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed, optional, half NULLs         1.05    110.0±2.47µs        ? ?/sec    1.00    105.0±1.37µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed, optional, no NULLs           1.01     81.4±0.33µs        ? ?/sec    1.00     80.2±0.23µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed skip, mandatory, no NULLs                1.00     37.8±0.51µs        ? ?/sec    1.00     37.7±0.68µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed skip, optional, half NULLs               1.00     48.9±0.21µs        ? ?/sec    1.03     50.2±0.53µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed skip, optional, no NULLs                 1.00     38.7±0.39µs        ? ?/sec    1.00     38.8±0.60µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed, mandatory, no NULLs                     1.01     51.4±0.52µs        ? ?/sec    1.00     50.9±0.72µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed, optional, half NULLs                    1.00     81.5±0.94µs        ? ?/sec    1.00     81.3±0.25µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed, optional, no NULLs                      1.00     53.6±0.22µs        ? ?/sec    1.00     53.6±0.40µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed skip, mandatory, no NULLs                1.01     38.3±0.28µs        ? ?/sec    1.00     37.8±0.20µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed skip, optional, half NULLs               1.00     47.4±0.33µs        ? ?/sec    1.01     47.8±0.36µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed skip, optional, no NULLs                 1.00     39.1±0.18µs        ? ?/sec    1.03     40.3±1.11µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed, mandatory, no NULLs                     1.01     47.4±0.18µs        ? ?/sec    1.00     46.9±0.31µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed, optional, half NULLs                    1.01     78.3±1.17µs        ? ?/sec    1.00     77.7±0.31µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed, optional, no NULLs                      1.00     52.2±0.35µs        ? ?/sec    1.00     52.3±0.66µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed skip, mandatory, no NULLs                1.00     40.2±0.15µs        ? ?/sec    1.01     40.6±0.14µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed skip, optional, half NULLs               1.00     49.7±0.26µs        ? ?/sec    1.00     49.6±0.23µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed skip, optional, no NULLs                 1.00     41.5±0.13µs        ? ?/sec    1.02     42.3±0.16µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed, mandatory, no NULLs                     1.00     54.8±0.25µs        ? ?/sec    1.02     56.0±0.22µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed, optional, half NULLs                    1.01     81.5±0.48µs        ? ?/sec    1.00     80.5±0.70µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed, optional, no NULLs                      1.00     56.9±0.31µs        ? ?/sec    1.01     57.4±0.22µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed skip, mandatory, no NULLs                 1.01     40.2±0.29µs        ? ?/sec    1.00     40.0±0.26µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed skip, optional, half NULLs                1.01     50.7±0.69µs        ? ?/sec    1.00     50.4±0.50µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed skip, optional, no NULLs                  1.00     41.5±0.19µs        ? ?/sec    1.00     41.4±0.24µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed, mandatory, no NULLs                      1.00     54.1±0.19µs        ? ?/sec    1.00     54.0±0.29µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed, optional, half NULLs                     1.00     84.3±0.32µs        ? ?/sec    1.00     84.1±1.11µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed, optional, no NULLs                       1.00     57.2±0.69µs        ? ?/sec    1.00     57.3±0.42µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed skip, mandatory, no NULLs               1.01     44.7±0.30µs        ? ?/sec    1.00     44.4±0.51µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed skip, optional, half NULLs              1.01     53.2±0.38µs        ? ?/sec    1.00     52.8±0.60µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed skip, optional, no NULLs                1.00     45.8±0.20µs        ? ?/sec    1.00     45.8±0.61µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed, mandatory, no NULLs                    1.01     59.9±0.27µs        ? ?/sec    1.00     59.5±0.28µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed, optional, half NULLs                   1.00     87.4±1.04µs        ? ?/sec    1.00     87.9±0.63µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed, optional, no NULLs                     1.01     62.7±0.56µs        ? ?/sec    1.00     62.2±0.51µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed skip, mandatory, no NULLs               1.01     38.8±0.67µs        ? ?/sec    1.00     38.5±0.69µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed skip, optional, half NULLs              1.00     48.2±0.20µs        ? ?/sec    1.00     48.1±0.23µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed skip, optional, no NULLs                1.00     40.1±0.44µs        ? ?/sec    1.00     40.2±0.42µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed, mandatory, no NULLs                    1.01     50.0±0.46µs        ? ?/sec    1.00     49.5±0.49µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed, optional, half NULLs                   1.00     77.7±0.34µs        ? ?/sec    1.01     78.1±0.24µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed, optional, no NULLs                     1.01     52.6±0.34µs        ? ?/sec    1.00     52.1±0.45µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed skip, mandatory, no NULLs               1.00     40.3±0.21µs        ? ?/sec    1.01     40.6±0.15µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed skip, optional, half NULLs              1.00     49.8±0.67µs        ? ?/sec    1.00     49.7±0.46µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed skip, optional, no NULLs                1.00     41.4±0.15µs        ? ?/sec    1.02     42.1±0.40µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed, mandatory, no NULLs                    1.00     55.5±0.31µs        ? ?/sec    1.01     56.1±0.53µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed, optional, half NULLs                   1.02     81.8±0.62µs        ? ?/sec    1.00     80.5±0.41µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed, optional, no NULLs                     1.00     57.5±1.01µs        ? ?/sec    1.00     57.3±0.67µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed skip, mandatory, no NULLs                1.01     42.7±0.52µs        ? ?/sec    1.00     42.4±0.23µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed skip, optional, half NULLs               1.00     52.3±0.40µs        ? ?/sec    1.00     52.0±0.72µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed skip, optional, no NULLs                 1.00     43.9±0.19µs        ? ?/sec    1.01     44.1±0.20µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed, mandatory, no NULLs                     1.03     57.7±0.89µs        ? ?/sec    1.00     56.1±0.26µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed, optional, half NULLs                    1.00     85.9±0.54µs        ? ?/sec    1.00     85.7±0.35µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed, optional, no NULLs                      1.00     59.9±0.19µs        ? ?/sec    1.01     60.6±0.69µs        ? ?/sec

@etseidl
Copy link
Contributor Author

etseidl commented Feb 25, 2026

Currently unknown what impact this optimization will have on the other delta encodings. There could be a good speedup for situations like constant length strings + DELTA_LENGTH_BYTE_ARRAY (think UUIDs or hashes), as well as long runs of the same prefix or long runs of strings with no shared prefix with DELTA_BYTE_ARRAY.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes DELTA_BINARY_PACKED decoding for the common case where a miniblock has bit_width == 0, aiming to match speedups observed in Arrow C++ and address issue #9476.

Changes:

  • Add a fast-path in the delta binary packed decoder for bit_width == 0 miniblocks (including constant-value and arithmetic-progression cases).
  • Add larger regression tests covering constant, increasing, and mixed patterns for Int32/Int64.
  • Add new benchmark cases targeting constant and monotonically increasing delta-encoded pages.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
parquet/src/encodings/decoding.rs Adds bit_width == 0 decoding fast-path and new large tests for delta decoding correctness.
parquet/benches/arrow_reader.rs Adds a page generator and benchmark cases for delta binary packed constant/increasing patterns.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if bit_width == 0 {
let min_delta = self.min_delta.as_i64()?;
if min_delta == 0 {
for v in &mut buffer[read..read + batch_read] {
Copy link
Contributor

Choose a reason for hiding this comment

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

this can use .fill() (if not faster, at least looks nice)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had done that, but on my laptop it was actually slower for some reason...I'll check again on a more modern processor. I do agree it would look nicer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, on my workstation fill is a bit faster. On my laptop it's a bit slower. I'll go with the workstation results 😁

// Kudos to @pitrou for the idea https://github.com/apache/arrow/pull/49296
if bit_width == 0 {
let min_delta = self.min_delta.as_i64()?;
if min_delta == 0 {
Copy link
Contributor

@Dandandan Dandandan Feb 28, 2026

Choose a reason for hiding this comment

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

Can we repeat the min_delta==0 optimization below as well for bit_width > 0 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can try. The theory, however, is that the speed up is from not having to use the previous value to calculate the current. I'll see if there's any speedup from avoiding the additional wrapping_add.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. It's good for 5-10% on my laptop.

@Dandandan
Copy link
Contributor

I think the code looks good! Lefr 2 comments

@Dandandan
Copy link
Contributor

run benchmark arrow_reader

@alamb-ghbot
Copy link

🤖 ./gh_compare_arrow.sh gh_compare_arrow.sh Running
Linux aal-dev 6.14.0-1018-gcp #19~24.04.1-Ubuntu SMP Wed Sep 24 23:23:09 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing delta_binary_bit_zero (7faa0d5) to a2cffdb diff
BENCH_NAME=arrow_reader
BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental,object_store --bench arrow_reader
BENCH_FILTER=
BENCH_BRANCH_NAME=delta_binary_bit_zero
Results will be posted here when complete

@alamb-ghbot
Copy link

🤖: Benchmark completed

Details

group                                                                                                      delta_binary_bit_zero                   main
-----                                                                                                      ---------------------                   ----
arrow_array_reader/BYTE_ARRAY/Decimal128Array/plain encoded, mandatory, no NULLs                           1.05  1230.0±15.71µs        ? ?/sec     1.00   1175.0±1.52µs        ? ?/sec
arrow_array_reader/BYTE_ARRAY/Decimal128Array/plain encoded, optional, half NULLs                          1.01   1245.9±5.13µs        ? ?/sec     1.00  1238.4±17.51µs        ? ?/sec
arrow_array_reader/BYTE_ARRAY/Decimal128Array/plain encoded, optional, no NULLs                            1.04   1230.9±3.69µs        ? ?/sec     1.00   1184.4±6.38µs        ? ?/sec
arrow_array_reader/BinaryArray/dictionary encoded, mandatory, no NULLs                                     1.01    482.9±3.43µs        ? ?/sec     1.00    476.7±4.67µs        ? ?/sec
arrow_array_reader/BinaryArray/dictionary encoded, optional, half NULLs                                    1.00    651.5±2.96µs        ? ?/sec     1.00    649.0±2.01µs        ? ?/sec
arrow_array_reader/BinaryArray/dictionary encoded, optional, no NULLs                                      1.01    486.5±3.92µs        ? ?/sec     1.00    484.0±4.71µs        ? ?/sec
arrow_array_reader/BinaryArray/plain encoded, mandatory, no NULLs                                          1.05    542.0±3.97µs        ? ?/sec     1.00   515.9±10.23µs        ? ?/sec
arrow_array_reader/BinaryArray/plain encoded, optional, half NULLs                                         1.00    715.4±4.22µs        ? ?/sec     1.01    723.4±8.75µs        ? ?/sec
arrow_array_reader/BinaryArray/plain encoded, optional, no NULLs                                           1.06    553.4±4.54µs        ? ?/sec     1.00   521.0±13.25µs        ? ?/sec
arrow_array_reader/BinaryViewArray/dictionary encoded, mandatory, no NULLs                                 1.01    157.8±2.34µs        ? ?/sec     1.00    155.6±2.40µs        ? ?/sec
arrow_array_reader/BinaryViewArray/dictionary encoded, optional, half NULLs                                1.03    207.7±0.61µs        ? ?/sec     1.00    202.3±1.28µs        ? ?/sec
arrow_array_reader/BinaryViewArray/dictionary encoded, optional, no NULLs                                  1.00    154.2±1.73µs        ? ?/sec     1.03    158.9±3.85µs        ? ?/sec
arrow_array_reader/BinaryViewArray/plain encoded, mandatory, no NULLs                                      1.03    215.9±4.24µs        ? ?/sec     1.00    209.3±6.63µs        ? ?/sec
arrow_array_reader/BinaryViewArray/plain encoded, mandatory, no NULLs, short string                        1.00    196.0±3.18µs        ? ?/sec     1.08    212.2±0.39µs        ? ?/sec
arrow_array_reader/BinaryViewArray/plain encoded, optional, half NULLs                                     1.07    246.8±2.56µs        ? ?/sec     1.00    231.4±2.62µs        ? ?/sec
arrow_array_reader/BinaryViewArray/plain encoded, optional, no NULLs                                       1.04    224.3±2.38µs        ? ?/sec     1.00    214.8±4.41µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Decimal128Array/byte_stream_split encoded, mandatory, no NULLs     1.00   1027.8±3.87µs        ? ?/sec     1.08   1105.5±7.98µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Decimal128Array/byte_stream_split encoded, optional, half NULLs    1.00    887.2±3.08µs        ? ?/sec     1.01    892.9±3.97µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Decimal128Array/byte_stream_split encoded, optional, no NULLs      1.00  1055.3±105.05µs        ? ?/sec    1.05  1112.4±12.98µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Decimal128Array/plain encoded, mandatory, no NULLs                 1.00    410.2±3.87µs        ? ?/sec     1.06    433.5±7.76µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Decimal128Array/plain encoded, optional, half NULLs                1.03   583.2±89.34µs        ? ?/sec     1.00    564.2±2.86µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Decimal128Array/plain encoded, optional, no NULLs                  1.00    411.1±1.73µs        ? ?/sec     1.08    442.6±8.73µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Float16Array/byte_stream_split encoded, mandatory, no NULLs        1.00    153.1±0.53µs        ? ?/sec     1.06    161.6±3.17µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Float16Array/byte_stream_split encoded, optional, half NULLs       1.05    318.1±3.39µs        ? ?/sec     1.00    302.0±3.33µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Float16Array/byte_stream_split encoded, optional, no NULLs         1.00    157.6±0.49µs        ? ?/sec     1.05    166.2±1.10µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Float16Array/plain encoded, mandatory, no NULLs                    1.00     76.4±0.34µs        ? ?/sec     1.01     77.2±0.95µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Float16Array/plain encoded, optional, half NULLs                   1.07    276.4±0.75µs        ? ?/sec     1.00    259.2±6.35µs        ? ?/sec
arrow_array_reader/FIXED_LEN_BYTE_ARRAY/Float16Array/plain encoded, optional, no NULLs                     1.00     81.1±0.53µs        ? ?/sec     1.01     81.7±2.03µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(16)/byte_stream_split encoded, mandatory, no NULLs                    1.00    683.9±7.97µs        ? ?/sec     1.08   737.3±14.08µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(16)/byte_stream_split encoded, optional, half NULLs                   1.00    537.2±1.55µs        ? ?/sec     1.00    538.9±2.79µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(16)/byte_stream_split encoded, optional, no NULLs                     1.00    688.3±2.27µs        ? ?/sec     1.08    740.9±6.33µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(16)/plain encoded, mandatory, no NULLs                                1.00     56.6±4.42µs        ? ?/sec     1.07     60.7±3.60µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(16)/plain encoded, optional, half NULLs                               1.13    231.2±1.86µs        ? ?/sec     1.00    204.8±0.55µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(16)/plain encoded, optional, no NULLs                                 1.00     62.9±6.64µs        ? ?/sec     1.06     66.5±3.91µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(2)/byte_stream_split encoded, mandatory, no NULLs                     1.00     85.6±0.42µs        ? ?/sec     1.09     93.6±0.40µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(2)/byte_stream_split encoded, optional, half NULLs                    1.07    248.2±3.25µs        ? ?/sec     1.00    232.7±3.55µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(2)/byte_stream_split encoded, optional, no NULLs                      1.00     89.9±0.85µs        ? ?/sec     1.08     97.3±0.37µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(2)/plain encoded, mandatory, no NULLs                                 1.02      9.3±0.17µs        ? ?/sec     1.00      9.0±0.19µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(2)/plain encoded, optional, half NULLs                                1.10    209.4±0.56µs        ? ?/sec     1.00    189.9±2.09µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(2)/plain encoded, optional, no NULLs                                  1.02     13.1±0.19µs        ? ?/sec     1.00     12.8±0.16µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(4)/byte_stream_split encoded, mandatory, no NULLs                     1.00    169.2±0.28µs        ? ?/sec     1.08    183.2±0.76µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(4)/byte_stream_split encoded, optional, half NULLs                    1.07    390.2±1.69µs        ? ?/sec     1.00    365.4±3.99µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(4)/byte_stream_split encoded, optional, no NULLs                      1.00    174.6±2.43µs        ? ?/sec     1.08    187.8±1.20µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(4)/plain encoded, mandatory, no NULLs                                 1.00     13.6±0.20µs        ? ?/sec     1.02     13.9±0.36µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(4)/plain encoded, optional, half NULLs                                1.11    313.4±1.15µs        ? ?/sec     1.00    281.1±1.13µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(4)/plain encoded, optional, no NULLs                                  1.00     18.1±0.35µs        ? ?/sec     1.02     18.4±0.60µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(8)/byte_stream_split encoded, mandatory, no NULLs                     1.00    341.4±8.72µs        ? ?/sec     1.07    366.2±1.53µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(8)/byte_stream_split encoded, optional, half NULLs                    1.03    355.8±1.62µs        ? ?/sec     1.00   346.4±21.97µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(8)/byte_stream_split encoded, optional, no NULLs                      1.00   350.4±27.99µs        ? ?/sec     1.06    371.3±1.08µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(8)/plain encoded, mandatory, no NULLs                                 1.00     25.5±0.51µs        ? ?/sec     1.00     25.4±0.37µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(8)/plain encoded, optional, half NULLs                                1.17    200.4±1.57µs        ? ?/sec     1.00    171.5±0.76µs        ? ?/sec
arrow_array_reader/FixedLenByteArray(8)/plain encoded, optional, no NULLs                                  1.02     32.2±0.20µs        ? ?/sec     1.00     31.5±0.37µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed increasing value                                    1.00     83.7±0.45µs        ? ?/sec   
arrow_array_reader/INT32/Decimal128Array/binary packed single value                                        1.00     80.0±0.34µs        ? ?/sec   
arrow_array_reader/INT32/Decimal128Array/binary packed skip, mandatory, no NULLs                           1.00    111.1±0.58µs        ? ?/sec     1.00    110.8±1.89µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed skip, optional, half NULLs                          1.00    119.5±1.77µs        ? ?/sec     1.00    119.0±0.53µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed skip, optional, no NULLs                            1.00    112.9±0.68µs        ? ?/sec     1.02    114.8±1.63µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed, mandatory, no NULLs                                1.01    162.2±0.30µs        ? ?/sec     1.00    161.3±0.49µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed, optional, half NULLs                               1.00    202.5±1.57µs        ? ?/sec     1.00   202.8±12.49µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/binary packed, optional, no NULLs                                 1.00    166.0±0.56µs        ? ?/sec     1.00    165.3±0.49µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/byte_stream_split encoded, mandatory, no NULLs                    1.04     76.9±0.16µs        ? ?/sec     1.00     73.7±0.32µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/byte_stream_split encoded, optional, half NULLs                   1.00    155.8±0.53µs        ? ?/sec     1.00    155.7±1.42µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/byte_stream_split encoded, optional, no NULLs                     1.00     79.2±0.16µs        ? ?/sec     1.02     80.6±0.26µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/dictionary encoded, mandatory, no NULLs                           1.00    134.9±2.01µs        ? ?/sec     1.08    145.4±0.89µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/dictionary encoded, optional, half NULLs                          1.00    189.6±0.45µs        ? ?/sec     1.03    195.8±1.59µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/dictionary encoded, optional, no NULLs                            1.00    139.6±0.73µs        ? ?/sec     1.07    148.8±0.54µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/plain encoded, mandatory, no NULLs                                1.00     72.0±0.32µs        ? ?/sec     1.02     73.8±0.36µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/plain encoded, optional, half NULLs                               1.01    154.2±0.46µs        ? ?/sec     1.00    153.2±0.64µs        ? ?/sec
arrow_array_reader/INT32/Decimal128Array/plain encoded, optional, no NULLs                                 1.00     76.0±0.22µs        ? ?/sec     1.02     77.3±0.19µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed increasing value                                    1.00     82.6±0.58µs        ? ?/sec   
arrow_array_reader/INT64/Decimal128Array/binary packed single value                                        1.00     81.4±2.74µs        ? ?/sec   
arrow_array_reader/INT64/Decimal128Array/binary packed skip, mandatory, no NULLs                           1.01    109.5±0.46µs        ? ?/sec     1.00    108.8±0.20µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed skip, optional, half NULLs                          1.00    131.6±1.02µs        ? ?/sec     1.00    131.5±4.24µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed skip, optional, no NULLs                            1.01    110.9±1.95µs        ? ?/sec     1.00    110.0±2.40µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed, mandatory, no NULLs                                1.04   167.0±13.77µs        ? ?/sec     1.00    160.3±0.34µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed, optional, half NULLs                               1.02    235.4±4.14µs        ? ?/sec     1.00    231.7±0.93µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/binary packed, optional, no NULLs                                 1.02    167.4±0.91µs        ? ?/sec     1.00    164.2±0.44µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/byte_stream_split encoded, mandatory, no NULLs                    1.00    201.5±0.55µs        ? ?/sec     1.00    202.2±0.65µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/byte_stream_split encoded, optional, half NULLs                   1.01    252.1±1.32µs        ? ?/sec     1.00    249.4±0.70µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/byte_stream_split encoded, optional, no NULLs                     1.00    206.4±0.74µs        ? ?/sec     1.00    207.3±1.26µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/dictionary encoded, mandatory, no NULLs                           1.08    152.4±1.35µs        ? ?/sec     1.00    141.4±1.38µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/dictionary encoded, optional, half NULLs                          1.04    230.5±1.16µs        ? ?/sec     1.00    222.3±3.55µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/dictionary encoded, optional, no NULLs                            1.07    158.1±1.29µs        ? ?/sec     1.00    147.5±1.12µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/plain encoded, mandatory, no NULLs                                1.00    102.8±0.61µs        ? ?/sec     1.07    110.1±1.08µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/plain encoded, optional, half NULLs                               1.06   204.3±18.20µs        ? ?/sec     1.00    193.2±0.54µs        ? ?/sec
arrow_array_reader/INT64/Decimal128Array/plain encoded, optional, no NULLs                                 1.00    108.7±1.19µs        ? ?/sec     1.05    114.7±1.56µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed increasing value                                               1.00     66.6±0.60µs        ? ?/sec   
arrow_array_reader/Int16Array/binary packed single value                                                   1.00     62.7±1.28µs        ? ?/sec   
arrow_array_reader/Int16Array/binary packed skip, mandatory, no NULLs                                      1.00     78.8±0.40µs        ? ?/sec     1.00     78.8±0.18µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed skip, optional, half NULLs                                     1.00     92.2±1.05µs        ? ?/sec     1.00     92.4±1.07µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed skip, optional, no NULLs                                       1.00     80.6±0.64µs        ? ?/sec     1.00     80.6±0.14µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed, mandatory, no NULLs                                           1.01    109.3±0.58µs        ? ?/sec     1.00    108.2±0.10µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed, optional, half NULLs                                          1.00    153.2±1.32µs        ? ?/sec     1.00    153.3±3.77µs        ? ?/sec
arrow_array_reader/Int16Array/binary packed, optional, no NULLs                                            1.01    112.9±2.01µs        ? ?/sec     1.00    111.5±0.83µs        ? ?/sec
arrow_array_reader/Int16Array/byte_stream_split encoded, mandatory, no NULLs                               1.00     42.7±0.09µs        ? ?/sec     1.01     43.1±1.87µs        ? ?/sec
arrow_array_reader/Int16Array/byte_stream_split encoded, optional, half NULLs                              1.00    117.3±0.37µs        ? ?/sec     1.01    118.0±1.84µs        ? ?/sec
arrow_array_reader/Int16Array/byte_stream_split encoded, optional, no NULLs                                1.00     45.5±0.08µs        ? ?/sec     1.00     45.5±0.22µs        ? ?/sec
arrow_array_reader/Int16Array/dictionary encoded, mandatory, no NULLs                                      1.00    101.6±0.34µs        ? ?/sec     1.10    111.5±0.45µs        ? ?/sec
arrow_array_reader/Int16Array/dictionary encoded, optional, half NULLs                                     1.00   156.6±20.41µs        ? ?/sec     1.01    157.4±2.77µs        ? ?/sec
arrow_array_reader/Int16Array/dictionary encoded, optional, no NULLs                                       1.00    105.3±0.87µs        ? ?/sec     1.09    114.6±0.87µs        ? ?/sec
arrow_array_reader/Int16Array/plain encoded, mandatory, no NULLs                                           1.00     36.7±0.07µs        ? ?/sec     1.00     36.6±0.10µs        ? ?/sec
arrow_array_reader/Int16Array/plain encoded, optional, half NULLs                                          1.00    115.1±0.26µs        ? ?/sec     1.00    114.9±0.25µs        ? ?/sec
arrow_array_reader/Int16Array/plain encoded, optional, no NULLs                                            1.01     40.1±0.10µs        ? ?/sec     1.00     39.6±0.20µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed increasing value                                               1.00     57.1±1.13µs        ? ?/sec   
arrow_array_reader/Int32Array/binary packed single value                                                   1.00     53.3±0.37µs        ? ?/sec   
arrow_array_reader/Int32Array/binary packed skip, mandatory, no NULLs                                      1.01     84.2±0.21µs        ? ?/sec     1.00     83.6±0.42µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed skip, optional, half NULLs                                     1.02     92.0±7.36µs        ? ?/sec     1.00     90.2±2.26µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed skip, optional, no NULLs                                       1.01     86.1±0.91µs        ? ?/sec     1.00     85.4±0.37µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed, mandatory, no NULLs                                           1.01    108.5±0.33µs        ? ?/sec     1.00    107.9±0.72µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed, optional, half NULLs                                          1.00    143.7±0.24µs        ? ?/sec     1.00    143.4±1.41µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed, optional, no NULLs                                            1.01    111.8±0.41µs        ? ?/sec     1.00    111.0±0.73µs        ? ?/sec
arrow_array_reader/Int32Array/byte_stream_split encoded, mandatory, no NULLs                               1.01     23.3±0.23µs        ? ?/sec     1.00     23.0±0.28µs        ? ?/sec
arrow_array_reader/Int32Array/byte_stream_split encoded, optional, half NULLs                              1.00     98.8±0.69µs        ? ?/sec     1.00     98.5±0.59µs        ? ?/sec
arrow_array_reader/Int32Array/byte_stream_split encoded, optional, no NULLs                                1.00     26.1±0.24µs        ? ?/sec     1.00     26.0±0.34µs        ? ?/sec
arrow_array_reader/Int32Array/dictionary encoded, mandatory, no NULLs                                      1.00     83.0±1.93µs        ? ?/sec     1.11     92.5±0.58µs        ? ?/sec
arrow_array_reader/Int32Array/dictionary encoded, optional, half NULLs                                     1.00    133.8±1.73µs        ? ?/sec     1.03    138.2±5.00µs        ? ?/sec
arrow_array_reader/Int32Array/dictionary encoded, optional, no NULLs                                       1.00     86.6±0.51µs        ? ?/sec     1.09     94.1±0.18µs        ? ?/sec
arrow_array_reader/Int32Array/plain encoded, mandatory, no NULLs                                           1.00     15.2±0.28µs        ? ?/sec     1.00     15.1±0.47µs        ? ?/sec
arrow_array_reader/Int32Array/plain encoded, optional, half NULLs                                          1.00     96.1±0.15µs        ? ?/sec     1.00     96.4±2.01µs        ? ?/sec
arrow_array_reader/Int32Array/plain encoded, optional, no NULLs                                            1.00     19.8±0.30µs        ? ?/sec     1.01     20.0±1.34µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed increasing value                                               1.00     53.3±0.31µs        ? ?/sec   
arrow_array_reader/Int64Array/binary packed single value                                                   1.00     52.2±0.42µs        ? ?/sec   
arrow_array_reader/Int64Array/binary packed skip, mandatory, no NULLs                                      1.00     79.7±0.25µs        ? ?/sec     1.00     79.5±0.46µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed skip, optional, half NULLs                                     1.01    102.7±0.94µs        ? ?/sec     1.00    101.4±1.24µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed skip, optional, no NULLs                                       1.02     83.1±4.35µs        ? ?/sec     1.00     81.2±0.36µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed, mandatory, no NULLs                                           1.02    107.7±0.42µs        ? ?/sec     1.00    105.8±0.37µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed, optional, half NULLs                                          1.05    174.9±0.41µs        ? ?/sec     1.00    166.7±0.62µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed, optional, no NULLs                                            1.01    111.1±0.56µs        ? ?/sec     1.00   110.0±10.02µs        ? ?/sec
arrow_array_reader/Int64Array/byte_stream_split encoded, mandatory, no NULLs                               1.00    146.9±0.61µs        ? ?/sec     1.00    146.7±0.33µs        ? ?/sec
arrow_array_reader/Int64Array/byte_stream_split encoded, optional, half NULLs                              1.00    191.4±0.43µs        ? ?/sec     1.01    192.6±2.47µs        ? ?/sec
arrow_array_reader/Int64Array/byte_stream_split encoded, optional, no NULLs                                1.00    150.4±0.57µs        ? ?/sec     1.00    150.2±0.40µs        ? ?/sec
arrow_array_reader/Int64Array/dictionary encoded, mandatory, no NULLs                                      1.11     97.9±0.84µs        ? ?/sec     1.00     87.9±0.36µs        ? ?/sec
arrow_array_reader/Int64Array/dictionary encoded, optional, half NULLs                                     1.05    166.9±0.93µs        ? ?/sec     1.00    159.5±1.31µs        ? ?/sec
arrow_array_reader/Int64Array/dictionary encoded, optional, no NULLs                                       1.11    101.3±0.72µs        ? ?/sec     1.00     91.1±0.50µs        ? ?/sec
arrow_array_reader/Int64Array/plain encoded, mandatory, no NULLs                                           1.10     41.6±1.10µs        ? ?/sec     1.00     37.8±0.62µs        ? ?/sec
arrow_array_reader/Int64Array/plain encoded, optional, half NULLs                                          1.02    136.0±0.59µs        ? ?/sec     1.00    133.5±0.30µs        ? ?/sec
arrow_array_reader/Int64Array/plain encoded, optional, no NULLs                                            1.14     46.5±0.74µs        ? ?/sec     1.00     40.7±0.67µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed increasing value                                                1.00     62.4±0.18µs        ? ?/sec   
arrow_array_reader/Int8Array/binary packed single value                                                    1.00     58.7±0.24µs        ? ?/sec   
arrow_array_reader/Int8Array/binary packed skip, mandatory, no NULLs                                       1.00     82.6±0.66µs        ? ?/sec     1.00     82.5±0.21µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed skip, optional, half NULLs                                      1.00     92.1±0.25µs        ? ?/sec     1.01     92.7±1.89µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed skip, optional, no NULLs                                        1.00     84.4±0.96µs        ? ?/sec     1.00     84.4±0.19µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed, mandatory, no NULLs                                            1.01    111.6±7.05µs        ? ?/sec     1.00    110.0±0.24µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed, optional, half NULLs                                           1.03   154.0±20.13µs        ? ?/sec     1.00    150.0±0.46µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed, optional, no NULLs                                             1.01    113.9±2.54µs        ? ?/sec     1.00    113.1±0.16µs        ? ?/sec
arrow_array_reader/Int8Array/byte_stream_split encoded, mandatory, no NULLs                                1.00     33.1±0.53µs        ? ?/sec     1.05     34.6±0.22µs        ? ?/sec
arrow_array_reader/Int8Array/byte_stream_split encoded, optional, half NULLs                               1.01    110.5±2.24µs        ? ?/sec     1.00    109.9±0.31µs        ? ?/sec
arrow_array_reader/Int8Array/byte_stream_split encoded, optional, no NULLs                                 1.00     37.6±0.80µs        ? ?/sec     1.00     37.6±0.19µs        ? ?/sec
arrow_array_reader/Int8Array/dictionary encoded, mandatory, no NULLs                                       1.00     94.1±0.38µs        ? ?/sec     1.10    103.7±0.78µs        ? ?/sec
arrow_array_reader/Int8Array/dictionary encoded, optional, half NULLs                                      1.00    144.5±0.33µs        ? ?/sec     1.04    149.7±1.28µs        ? ?/sec
arrow_array_reader/Int8Array/dictionary encoded, optional, no NULLs                                        1.00     97.5±0.19µs        ? ?/sec     1.09    106.8±0.53µs        ? ?/sec
arrow_array_reader/Int8Array/plain encoded, mandatory, no NULLs                                            1.00     28.7±0.08µs        ? ?/sec     1.00     28.9±0.12µs        ? ?/sec
arrow_array_reader/Int8Array/plain encoded, optional, half NULLs                                           1.00    106.9±0.25µs        ? ?/sec     1.01    108.3±0.25µs        ? ?/sec
arrow_array_reader/Int8Array/plain encoded, optional, no NULLs                                             1.00     32.1±0.08µs        ? ?/sec     1.00     32.2±0.18µs        ? ?/sec
arrow_array_reader/ListArray/plain encoded optional strings half NULLs                                     1.01      6.1±0.21ms        ? ?/sec     1.00      6.0±0.15ms        ? ?/sec
arrow_array_reader/ListArray/plain encoded optional strings no NULLs                                       1.00     12.0±0.13ms        ? ?/sec     1.00     11.9±0.13ms        ? ?/sec
arrow_array_reader/StringArray/dictionary encoded, mandatory, no NULLs                                     1.00    495.4±4.20µs        ? ?/sec     1.01   502.3±63.85µs        ? ?/sec
arrow_array_reader/StringArray/dictionary encoded, optional, half NULLs                                    1.00    650.4±2.15µs        ? ?/sec     1.00   652.8±10.07µs        ? ?/sec
arrow_array_reader/StringArray/dictionary encoded, optional, no NULLs                                      1.00    486.5±3.52µs        ? ?/sec     1.03    500.0±4.92µs        ? ?/sec
arrow_array_reader/StringArray/plain encoded, mandatory, no NULLs                                          1.04    677.9±6.09µs        ? ?/sec     1.00    649.6±4.02µs        ? ?/sec
arrow_array_reader/StringArray/plain encoded, optional, half NULLs                                         1.03    785.9±4.98µs        ? ?/sec     1.00    760.4±4.29µs        ? ?/sec
arrow_array_reader/StringArray/plain encoded, optional, no NULLs                                           1.07  703.8±105.92µs        ? ?/sec     1.00   659.6±10.10µs        ? ?/sec
arrow_array_reader/StringDictionary/dictionary encoded, mandatory, no NULLs                                1.01    332.0±1.19µs        ? ?/sec     1.00    328.8±5.49µs        ? ?/sec
arrow_array_reader/StringDictionary/dictionary encoded, optional, half NULLs                               1.02    421.4±1.15µs        ? ?/sec     1.00   414.7±20.39µs        ? ?/sec
arrow_array_reader/StringDictionary/dictionary encoded, optional, no NULLs                                 1.00    336.5±1.93µs        ? ?/sec     1.02   342.8±47.80µs        ? ?/sec
arrow_array_reader/StringViewArray/dictionary encoded, mandatory, no NULLs                                 1.00    147.9±1.71µs        ? ?/sec     1.04    153.4±2.93µs        ? ?/sec
arrow_array_reader/StringViewArray/dictionary encoded, optional, half NULLs                                1.06    207.2±0.72µs        ? ?/sec     1.00    194.6±2.03µs        ? ?/sec
arrow_array_reader/StringViewArray/dictionary encoded, optional, no NULLs                                  1.00    152.4±3.02µs        ? ?/sec     1.00    152.4±3.17µs        ? ?/sec
arrow_array_reader/StringViewArray/plain encoded, mandatory, no NULLs                                      1.00    364.0±2.85µs        ? ?/sec     1.10    402.0±5.70µs        ? ?/sec
arrow_array_reader/StringViewArray/plain encoded, optional, half NULLs                                     1.00    318.5±1.92µs        ? ?/sec     1.03   328.6±29.96µs        ? ?/sec
arrow_array_reader/StringViewArray/plain encoded, optional, no NULLs                                       1.00    373.8±2.55µs        ? ?/sec     1.10   410.7±10.78µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed increasing value                                              1.00     66.3±0.18µs        ? ?/sec   
arrow_array_reader/UInt16Array/binary packed single value                                                  1.00     62.5±0.19µs        ? ?/sec   
arrow_array_reader/UInt16Array/binary packed skip, mandatory, no NULLs                                     1.00     94.1±0.28µs        ? ?/sec     1.00     93.6±0.17µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed skip, optional, half NULLs                                    1.01    101.2±2.45µs        ? ?/sec     1.00    100.4±0.59µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed skip, optional, no NULLs                                      1.00     96.2±1.02µs        ? ?/sec     1.00     96.0±2.60µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed, mandatory, no NULLs                                          1.01    128.5±0.32µs        ? ?/sec     1.00    127.5±0.35µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed, optional, half NULLs                                         1.00    163.8±0.48µs        ? ?/sec     1.00    163.5±0.43µs        ? ?/sec
arrow_array_reader/UInt16Array/binary packed, optional, no NULLs                                           1.01    131.9±0.35µs        ? ?/sec     1.00    130.6±0.32µs        ? ?/sec
arrow_array_reader/UInt16Array/byte_stream_split encoded, mandatory, no NULLs                              1.00     41.0±0.30µs        ? ?/sec     1.00     40.9±0.06µs        ? ?/sec
arrow_array_reader/UInt16Array/byte_stream_split encoded, optional, half NULLs                             1.00    117.6±0.32µs        ? ?/sec     1.00    117.2±0.29µs        ? ?/sec
arrow_array_reader/UInt16Array/byte_stream_split encoded, optional, no NULLs                               1.00     44.1±0.20µs        ? ?/sec     1.00     44.1±0.19µs        ? ?/sec
arrow_array_reader/UInt16Array/dictionary encoded, mandatory, no NULLs                                     1.00    101.8±0.36µs        ? ?/sec     1.09    111.0±0.59µs        ? ?/sec
arrow_array_reader/UInt16Array/dictionary encoded, optional, half NULLs                                    1.00    152.0±0.95µs        ? ?/sec     1.03    156.5±0.25µs        ? ?/sec
arrow_array_reader/UInt16Array/dictionary encoded, optional, no NULLs                                      1.00    105.3±0.36µs        ? ?/sec     1.08    114.0±0.20µs        ? ?/sec
arrow_array_reader/UInt16Array/plain encoded, mandatory, no NULLs                                          1.00     36.8±0.17µs        ? ?/sec     1.00     36.7±0.17µs        ? ?/sec
arrow_array_reader/UInt16Array/plain encoded, optional, half NULLs                                         1.00    114.9±1.14µs        ? ?/sec     1.00    115.1±0.21µs        ? ?/sec
arrow_array_reader/UInt16Array/plain encoded, optional, no NULLs                                           1.00     40.0±0.36µs        ? ?/sec     1.00     39.8±0.10µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed increasing value                                              1.00     57.1±0.25µs        ? ?/sec   
arrow_array_reader/UInt32Array/binary packed single value                                                  1.00     54.0±0.29µs        ? ?/sec   
arrow_array_reader/UInt32Array/binary packed skip, mandatory, no NULLs                                     1.01     84.3±0.90µs        ? ?/sec     1.00     83.6±0.18µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed skip, optional, half NULLs                                    1.01     90.9±0.25µs        ? ?/sec     1.00     90.2±0.24µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed skip, optional, no NULLs                                      1.04    89.3±12.40µs        ? ?/sec     1.00     85.6±0.32µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed, mandatory, no NULLs                                          1.05   113.1±16.62µs        ? ?/sec     1.00    108.0±0.24µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed, optional, half NULLs                                         1.01    145.0±3.00µs        ? ?/sec     1.00    143.8±0.47µs        ? ?/sec
arrow_array_reader/UInt32Array/binary packed, optional, no NULLs                                           1.01    112.2±0.52µs        ? ?/sec     1.00    111.1±0.34µs        ? ?/sec
arrow_array_reader/UInt32Array/byte_stream_split encoded, mandatory, no NULLs                              1.00     23.7±0.12µs        ? ?/sec     1.03     24.3±0.43µs        ? ?/sec
arrow_array_reader/UInt32Array/byte_stream_split encoded, optional, half NULLs                             1.01     99.8±1.80µs        ? ?/sec     1.00     98.7±0.31µs        ? ?/sec
arrow_array_reader/UInt32Array/byte_stream_split encoded, optional, no NULLs                               1.00     26.9±0.30µs        ? ?/sec     1.01     27.2±0.37µs        ? ?/sec
arrow_array_reader/UInt32Array/dictionary encoded, mandatory, no NULLs                                     1.00     83.3±0.61µs        ? ?/sec     1.11     92.8±0.45µs        ? ?/sec
arrow_array_reader/UInt32Array/dictionary encoded, optional, half NULLs                                    1.00    133.5±0.39µs        ? ?/sec     1.04    138.3±1.70µs        ? ?/sec
arrow_array_reader/UInt32Array/dictionary encoded, optional, no NULLs                                      1.00     86.8±0.43µs        ? ?/sec     1.11     95.9±0.83µs        ? ?/sec
arrow_array_reader/UInt32Array/plain encoded, mandatory, no NULLs                                          1.01     18.2±0.60µs        ? ?/sec     1.00     18.0±0.85µs        ? ?/sec
arrow_array_reader/UInt32Array/plain encoded, optional, half NULLs                                         1.00     95.8±0.52µs        ? ?/sec     1.00     95.8±0.38µs        ? ?/sec
arrow_array_reader/UInt32Array/plain encoded, optional, no NULLs                                           1.00     21.5±0.40µs        ? ?/sec     1.02     21.9±0.67µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed increasing value                                              1.00     53.8±0.46µs        ? ?/sec   
arrow_array_reader/UInt64Array/binary packed single value                                                  1.00     52.8±0.63µs        ? ?/sec   
arrow_array_reader/UInt64Array/binary packed skip, mandatory, no NULLs                                     1.01     80.3±0.25µs        ? ?/sec     1.00     79.5±0.84µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed skip, optional, half NULLs                                    1.02    102.8±0.65µs        ? ?/sec     1.00    101.0±0.67µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed skip, optional, no NULLs                                      1.01     82.1±0.33µs        ? ?/sec     1.00     80.9±0.53µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed, mandatory, no NULLs                                          1.01    108.1±0.57µs        ? ?/sec     1.00    106.8±0.92µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed, optional, half NULLs                                         1.00    169.7±0.90µs        ? ?/sec     1.02    172.4±1.37µs        ? ?/sec
arrow_array_reader/UInt64Array/binary packed, optional, no NULLs                                           1.04   113.1±12.63µs        ? ?/sec     1.00    108.6±0.89µs        ? ?/sec
arrow_array_reader/UInt64Array/byte_stream_split encoded, mandatory, no NULLs                              1.00    145.7±0.36µs        ? ?/sec     1.00    145.2±0.76µs        ? ?/sec
arrow_array_reader/UInt64Array/byte_stream_split encoded, optional, half NULLs                             1.00    192.4±0.84µs        ? ?/sec     1.00    192.5±5.65µs        ? ?/sec
arrow_array_reader/UInt64Array/byte_stream_split encoded, optional, no NULLs                               1.00    149.1±0.35µs        ? ?/sec     1.00    149.1±0.78µs        ? ?/sec
arrow_array_reader/UInt64Array/dictionary encoded, mandatory, no NULLs                                     1.12     98.4±0.48µs        ? ?/sec     1.00     87.7±0.61µs        ? ?/sec
arrow_array_reader/UInt64Array/dictionary encoded, optional, half NULLs                                    1.05    167.5±6.74µs        ? ?/sec     1.00    158.9±0.89µs        ? ?/sec
arrow_array_reader/UInt64Array/dictionary encoded, optional, no NULLs                                      1.11    101.7±0.46µs        ? ?/sec     1.00     91.8±0.90µs        ? ?/sec
arrow_array_reader/UInt64Array/plain encoded, mandatory, no NULLs                                          1.00     43.2±0.88µs        ? ?/sec     1.04     44.8±3.05µs        ? ?/sec
arrow_array_reader/UInt64Array/plain encoded, optional, half NULLs                                         1.01    137.1±0.84µs        ? ?/sec     1.00    136.2±5.18µs        ? ?/sec
arrow_array_reader/UInt64Array/plain encoded, optional, no NULLs                                           1.00     46.8±0.93µs        ? ?/sec     1.03     48.2±2.30µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed increasing value                                               1.00     63.2±0.65µs        ? ?/sec   
arrow_array_reader/UInt8Array/binary packed single value                                                   1.00     59.3±0.27µs        ? ?/sec   
arrow_array_reader/UInt8Array/binary packed skip, mandatory, no NULLs                                      1.03     92.2±1.28µs        ? ?/sec     1.00     89.2±0.10µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed skip, optional, half NULLs                                     1.02     97.3±0.15µs        ? ?/sec     1.00     95.3±0.32µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed skip, optional, no NULLs                                       1.03     94.1±0.24µs        ? ?/sec     1.00     91.1±0.48µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed, mandatory, no NULLs                                           1.02    120.7±4.01µs        ? ?/sec     1.00    118.9±0.12µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed, optional, half NULLs                                          1.01    155.9±3.76µs        ? ?/sec     1.00    154.3±0.31µs        ? ?/sec
arrow_array_reader/UInt8Array/binary packed, optional, no NULLs                                            1.01    123.5±0.64µs        ? ?/sec     1.00    122.0±0.21µs        ? ?/sec
arrow_array_reader/UInt8Array/byte_stream_split encoded, mandatory, no NULLs                               1.00     33.0±0.10µs        ? ?/sec     1.05     34.6±0.59µs        ? ?/sec
arrow_array_reader/UInt8Array/byte_stream_split encoded, optional, half NULLs                              1.00    109.9±0.31µs        ? ?/sec     1.04   114.3±14.08µs        ? ?/sec
arrow_array_reader/UInt8Array/byte_stream_split encoded, optional, no NULLs                                1.02     38.3±3.35µs        ? ?/sec     1.00     37.5±0.65µs        ? ?/sec
arrow_array_reader/UInt8Array/dictionary encoded, mandatory, no NULLs                                      1.00     94.1±0.67µs        ? ?/sec     1.10    103.7±0.26µs        ? ?/sec
arrow_array_reader/UInt8Array/dictionary encoded, optional, half NULLs                                     1.00    144.8±0.96µs        ? ?/sec     1.03    149.1±0.29µs        ? ?/sec
arrow_array_reader/UInt8Array/dictionary encoded, optional, no NULLs                                       1.00     97.4±0.44µs        ? ?/sec     1.09    106.2±0.84µs        ? ?/sec
arrow_array_reader/UInt8Array/plain encoded, mandatory, no NULLs                                           1.01     29.1±0.09µs        ? ?/sec     1.00     28.7±0.44µs        ? ?/sec
arrow_array_reader/UInt8Array/plain encoded, optional, half NULLs                                          1.00    107.0±0.39µs        ? ?/sec     1.00    107.5±1.02µs        ? ?/sec
arrow_array_reader/UInt8Array/plain encoded, optional, no NULLs                                            1.00     32.0±0.09µs        ? ?/sec     1.00     32.0±0.61µs        ? ?/sec
arrow_array_reader/struct/Int32Array/plain encoded, mandatory struct, optional data, half NULLs            1.00     95.7±0.66µs        ? ?/sec     1.04     99.1±0.41µs        ? ?/sec
arrow_array_reader/struct/Int32Array/plain encoded, mandatory struct, optional data, no NULLs              1.00     21.6±0.89µs        ? ?/sec     1.01     21.8±1.34µs        ? ?/sec
arrow_array_reader/struct/Int32Array/plain encoded, optional struct, optional data, half NULLs             1.02    223.1±1.69µs        ? ?/sec     1.00    218.4±0.96µs        ? ?/sec
arrow_array_reader/struct/Int32Array/plain encoded, optional struct, optional data, no NULLs               1.04    123.4±1.57µs        ? ?/sec     1.00    118.9±1.96µs        ? ?/sec

assert_eq!(count, EXPECTED_VALUE_COUNT);
});

// binary packed same value
Copy link
Contributor

@Dandandan Dandandan Mar 2, 2026

Choose a reason for hiding this comment

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

Can you submit a PR for just these benchmarks, so we can run the benchmarks on this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do have a separate branch for the benches (and will submit separately), but combined them in this draft. I'd like to do some tests with the other delta encodings to see if the optimization here has an impact.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, done. #9500

@etseidl etseidl force-pushed the delta_binary_bit_zero branch from 7faa0d5 to 6fc5504 Compare March 2, 2026 18:35
@etseidl etseidl force-pushed the delta_binary_bit_zero branch from 6fc5504 to 70b9772 Compare March 2, 2026 18:47
@etseidl etseidl force-pushed the delta_binary_bit_zero branch from 7e08a52 to 65aef7b Compare March 2, 2026 20:08
@etseidl etseidl force-pushed the delta_binary_bit_zero branch from 65aef7b to 3b016c4 Compare March 2, 2026 22:00
@etseidl etseidl force-pushed the delta_binary_bit_zero branch from 0c5781b to 64626cc Compare March 3, 2026 17:47
@etseidl
Copy link
Contributor Author

etseidl commented Mar 3, 2026

Sampling from the latest bench against #9500. The 'stepped' benches trigger the optimization suggested by @Dandandan (#9477 (comment)). The StringArray benches are contrived to also trigger the optimizations here to show there is a small effect for the delta binary encodings.

group                                                                                        main2                                  opt2
-----                                                                                        -----                                  ----
arrow_array_reader/Int32Array/binary packed increasing value                                 1.19     32.4±0.15µs        ? ?/sec    1.00     27.1±0.17µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed single value                                     1.26     32.4±0.16µs        ? ?/sec    1.00     25.7±0.24µs        ? ?/sec
arrow_array_reader/Int32Array/binary packed stepped increasing value                         1.07     37.0±0.17µs        ? ?/sec    1.00     34.7±0.22µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed increasing value                                 1.22     35.3±0.33µs        ? ?/sec    1.00     29.0±0.31µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed single value                                     1.20     35.2±0.13µs        ? ?/sec    1.00     29.2±0.11µs        ? ?/sec
arrow_array_reader/Int64Array/binary packed stepped increasing value                         1.13     40.2±0.21µs        ? ?/sec    1.00     35.6±0.14µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed increasing value                                  1.18     37.6±0.30µs        ? ?/sec    1.00     31.9±0.11µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed single value                                      1.21     37.6±0.15µs        ? ?/sec    1.00     31.0±0.20µs        ? ?/sec
arrow_array_reader/Int8Array/binary packed stepped increasing value                          1.06     42.0±0.25µs        ? ?/sec    1.00     39.8±0.30µs        ? ?/sec
arrow_array_reader/StringArray/const delta byte array encoded, mandatory, no NULLs           1.09    525.4±6.63µs        ? ?/sec    1.00    482.8±4.25µs        ? ?/sec
arrow_array_reader/StringArray/const delta length byte array encoded, mandatory, no NULLs    1.03    380.8±2.70µs        ? ?/sec    1.00    369.7±2.92µs        ? ?/sec
arrow_array_reader/StringArray/const prefix delta byte array encoded, mandatory, no NULLs    1.04    621.6±2.99µs        ? ?/sec    1.00    596.0±3.44µs        ? ?/sec

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

Labels

parquet Changes to the parquet crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speedup DELTA_BINARY_PACKED decoding when bitwidth is 0

4 participants