This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-11406-9d1a049a4b28c7e5bb974c69fc6b6063ddcaa424
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git

commit b77170d3c1c958b2bf3d3ccfa3287cbdc9dd7936
Author: Neil Conway <[email protected]>
AuthorDate: Wed Oct 7 14:12:39 2026 +0000

    bench(parquet): add list benchmarks that skip and read in short runs 
(#11406)
    
    # Which issue does this PR close?
    
    - N/A
    
    # Rationale for this change
    
    The `ListArray` benchmarks read whole batches of 8192 records. A reader
    applying a `RowSelection` with short runs instead alternates between
    `skip_records` and `read_records` calls of a few records each, so
    per-call costs in the level decoders matter much more. No benchmark
    measures this for lists.
    
    # What changes are included in this PR?
    
    Add `Int32List` cases that alternately skip and read runs of 1 record
    (the worst case) and of 32 records (by default, selections whose runs
    average fewer than 32 rows are read with a mask instead).
    
    # Are these changes tested?
    
    Benchmark-only change.
    
    # Are there any significant user-facing changes?
    
    No.
---
 parquet/benches/arrow_reader.rs | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/parquet/benches/arrow_reader.rs b/parquet/benches/arrow_reader.rs
index dadd4516cb..3b23628009 100644
--- a/parquet/benches/arrow_reader.rs
+++ b/parquet/benches/arrow_reader.rs
@@ -986,6 +986,28 @@ fn bench_array_reader_skip(mut array_reader: Box<dyn 
ArrayReader>) -> usize {
     total_count
 }
 
+/// Alternately skips and reads `run_len` records, as when reading a row
+/// selection made of short runs, and emits a batch every `BATCH_SIZE` records 
read
+fn bench_array_reader_runs(mut array_reader: Box<dyn ArrayReader>, run_len: 
usize) -> usize {
+    let mut total_count = 0;
+    let mut batch_count = 0;
+    loop {
+        let skipped = array_reader.skip_records(run_len).unwrap();
+        let read = array_reader.read_records(run_len).unwrap();
+        total_count += skipped + read;
+        batch_count += read;
+        if batch_count >= BATCH_SIZE {
+            array_reader.consume_batch().unwrap();
+            batch_count = 0;
+        }
+        if read < run_len {
+            break;
+        }
+    }
+    array_reader.consume_batch().unwrap();
+    total_count
+}
+
 fn create_primitive_array_reader(
     page_iterator: impl PageIterator + 'static,
     column_desc: ColumnDescPtr,
@@ -2654,6 +2676,17 @@ fn add_benches(c: &mut Criterion) {
         });
         assert_eq!(count, EXPECTED_VALUE_COUNT);
     });
+    let list_data = build_int32_list_page_iterator(int32_list_desc.clone(), 
0.0, 0);
+    for run_len in [1, 32] {
+        let label = format!("no NULLs, skip and read in runs of {run_len}");
+        group.bench_function(label, |b| {
+            b.iter(|| {
+                let reader = create_int32_list_reader(list_data.clone(), 
int32_list_desc.clone());
+                count = bench_array_reader_runs(reader, run_len);
+            });
+            assert_eq!(count, EXPECTED_VALUE_COUNT);
+        });
+    }
     group.finish();
 
     let mut group = 
c.benchmark_group("arrow_array_reader/ListArray/Fixed32List");

Reply via email to