This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new f698c259f0 bench(variant): add list-index lookup with empty lists
(#11193)
f698c259f0 is described below
commit f698c259f0fbba91ad667a8c1b27d617acd1a34d
Author: Yifan Chen <[email protected]>
AuthorDate: Fri Oct 2 17:47:02 2026 +0000
bench(variant): add list-index lookup with empty lists (#11193)
# Which issue does this PR close?
Related to #11101 and #11052.
# Rationale for this change
Add a small benchmark for `variant_get` list-index lookup when some rows
are empty lists.
# What changes are included in this PR?
Two benchmark functions in the existing `variant_kernels` target,
following the nearby cases. The first builds 8,192 rows alternating
empty and two-element integer lists, then looks up index zero with
Variant output. The same fixture is timed unshredded and shredded as a
List of Int64. Fixture construction, shredding, and path setup are
outside timing; options cloning and output destruction are included.
The second restores the previously regressing small case: 64 one-element
`[1]` lists shredded as List<Int64>, index 9 (all out of bounds), and
Int64 output. It checks that all 64 results are null before timing. The
benchmark name is `variant_get_list_index_all_oob_int64_64_rows`.
# Are these changes tested?
- `cargo bench --locked -p parquet-variant-compute --bench
variant_kernels -- variant_get_list_index --test`: all three cases pass.
- Focused Criterion runs completed the mixed-list cases and the all-OOB
case (50 samples, 1 s warm-up, 3 s measurement).
- `cargo test --locked -p parquet-variant-compute`: 367 unit tests and
13 doc tests passed for the previous revision; this benchmark-only
follow-up was validated with the benchmark smoke run, Criterion, Clippy,
and formatting.
- `cargo clippy --locked -p parquet-variant-compute --all-targets
--all-features -- -D warnings`
- `cargo fmt --all -- --check`, `git diff --check`, and the repository
spelling check with typos 1.37.0 pass.
The benchmark runs on the existing baseline without asserting the
missing-index validity behavior that #11052 fixes. Unshredded and
shredded outputs currently differ in validity on empty rows, so these
timings do not establish an equivalent-output speedup or the cost of
that correctness fix. The earlier ~24% overhead observed in the separate
64-row all-OOB Int64 case remains unresolved; adding its benchmark does
not change that result.
# Are there any user-facing changes?
No. This only adds a benchmark; production code and dependencies are
unchanged.
# AI usage
OpenAI Codex generated this benchmark revision, ran the validation, and
drafted this description and review reply.
---
parquet-variant-compute/benches/variant_kernels.rs | 51 ++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/parquet-variant-compute/benches/variant_kernels.rs
b/parquet-variant-compute/benches/variant_kernels.rs
index 373a66cdd8..0d35d68901 100644
--- a/parquet-variant-compute/benches/variant_kernels.rs
+++ b/parquet-variant-compute/benches/variant_kernels.rs
@@ -180,6 +180,55 @@ pub fn variant_get_bench(c: &mut Criterion) {
});
}
+pub fn variant_get_list_index_bench(c: &mut Criterion) {
+ let mut builder = VariantArrayBuilder::new(8192);
+ for i in 0..8192 {
+ let mut list = builder.new_list();
+ // Alternate empty lists with two-element lists to exercise missing
and present indexes.
+ if i % 2 != 0 {
+ list.append_value(Variant::Int64(i));
+ list.append_value(Variant::Int64(i + 1));
+ }
+ list.finish();
+ }
+ let variant_array = builder.build();
+ let list_type = DataType::List(Arc::new(Field::new("item",
DataType::Int64, true)));
+ let shredded = shred_variant(&variant_array, &list_type).unwrap();
+ let options = GetOptions::new_with_path(VariantPath::from(0));
+
+ let input = ArrayRef::from(variant_array);
+ c.bench_function("variant_get_list_index_unshredded", |b| {
+ b.iter(|| variant_get(&input, options.clone()).unwrap())
+ });
+
+ let input = ArrayRef::from(shredded);
+ c.bench_function("variant_get_list_index_shredded", |b| {
+ b.iter(|| variant_get(&input, options.clone()).unwrap())
+ });
+}
+
+pub fn variant_get_list_index_all_oob_int64_bench(c: &mut Criterion) {
+ let mut builder = VariantArrayBuilder::new(64);
+ for _ in 0..64 {
+ let mut list = builder.new_list();
+ list.append_value(Variant::Int64(1));
+ list.finish();
+ }
+ let variant_array = builder.build();
+ let list_type = DataType::List(Arc::new(Field::new("item",
DataType::Int64, true)));
+ let input = ArrayRef::from(shred_variant(&variant_array,
&list_type).unwrap());
+ let options = GetOptions::new_with_path(VariantPath::from(9))
+ .with_as_type(Some(Arc::new(Field::new("value", DataType::Int64,
true))));
+ let result = variant_get(&input, options.clone()).unwrap();
+ assert_eq!(result.data_type(), &DataType::Int64);
+ assert_eq!(result.len(), 64);
+ assert_eq!(result.null_count(), 64);
+
+ c.bench_function("variant_get_list_index_all_oob_int64_64_rows", |b| {
+ b.iter(|| variant_get(&input, options.clone()).unwrap())
+ });
+}
+
pub fn variant_get_shredded_utf8_bench(c: &mut Criterion) {
let variant_array = create_shredded_utf8_variant_array(8192);
let input = ArrayRef::from(variant_array);
@@ -474,6 +523,8 @@ pub fn variant_get_binary_from_string_bench(c: &mut
Criterion) {
criterion_group!(
benches,
variant_get_bench,
+ variant_get_list_index_bench,
+ variant_get_list_index_all_oob_int64_bench,
variant_get_shredded_utf8_bench,
variant_get_unshredded_object_path_bench,
shred_variant_partial_object_bench,