This is an automated email from the ASF dual-hosted git repository.
Jefffrey 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 543b806925 bench(arrow): add fsl/map interleave benchmark (#10322)
543b806925 is described below
commit 543b8069252976d0d3e0dd73e33e555a5110010c
Author: mwish <[email protected]>
AuthorDate: Sun Jul 12 10:10:23 2026 +0800
bench(arrow): add fsl/map interleave benchmark (#10322)
Add benchmark test cases for FixedSizeList and Map array interleave
along with helper functions to create test arrays.
# Which issue does this PR close?
- Closes #10321 .
# Rationale for this change
Add benchmark for fsl/map interleave
# What changes are included in this PR?
Add benchmark for fsl/map interleave
# Are these changes tested?
No
# Are there any user-facing changes?
No
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
arrow/benches/interleave_kernels.rs | 10 +++++
arrow/src/util/bench_util.rs | 80 ++++++++++++++++++++++++++++++++++++-
2 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/arrow/benches/interleave_kernels.rs
b/arrow/benches/interleave_kernels.rs
index 4c4f5364ff..6ef38d9a71 100644
--- a/arrow/benches/interleave_kernels.rs
+++ b/arrow/benches/interleave_kernels.rs
@@ -150,6 +150,12 @@ fn add_benchmark(c: &mut Criterion) {
)
};
+ let fsl_i64 = create_primitive_fixed_size_list_array::<Int64Type>(8192,
0.0, 0.0, 5);
+ let fsl_i64_nulls =
create_primitive_fixed_size_list_array::<Int64Type>(8192, 0.1, 0.1, 5);
+
+ let map_str_i64 = create_string_map_array::<Int64Type>(8192, 0.0, 5, 8);
+ let map_str_i64_nulls = create_string_map_array::<Int64Type>(8192, 0.1, 5,
8);
+
let ree_run_ends = Int32Array::from_iter_values((1..=64).map(|i| i * 16));
let ree_i64_values = create_primitive_array::<Int64Type>(64, 0.0);
let ree_i64 = RunArray::<Int32Type>::try_new(&ree_run_ends,
&ree_i64_values).unwrap();
@@ -183,6 +189,10 @@ fn add_benchmark(c: &mut Criterion) {
("list_view<i64>(0.1,0.1,20)", &list_view_i64),
("list_view<i64>(0.0,0.0,20)", &list_view_i64_no_nulls),
("list_view_overlapping<i64>(80x,20)", &list_view_overlapping),
+ ("fixed_size_list<i64,5>(0.0,0.0)", &fsl_i64),
+ ("fixed_size_list<i64,5>(0.1,0.1)", &fsl_i64_nulls),
+ ("map<utf8,i64>(0.0,5,8)", &map_str_i64),
+ ("map<utf8,i64>(0.1,5,8)", &map_str_i64_nulls),
("ree_i32<i64>(64 runs)", &ree_i64),
("ree_i32<dict<u32,utf8>>(64 runs)", &ree_dict),
];
diff --git a/arrow/src/util/bench_util.rs b/arrow/src/util/bench_util.rs
index d8dce50961..cde0bc1d20 100644
--- a/arrow/src/util/bench_util.rs
+++ b/arrow/src/util/bench_util.rs
@@ -20,17 +20,19 @@
use crate::array::*;
use crate::datatypes::*;
use crate::util::test_util::seedable_rng;
-use arrow_buffer::{Buffer, IntervalMonthDayNano};
+use arrow_buffer::{Buffer, IntervalMonthDayNano, NullBuffer};
+use arrow_schema::Field;
use half::f16;
use rand::Rng;
use rand::SeedableRng;
use rand::distr::uniform::SampleUniform;
use rand::rng;
use rand::{
- distr::{Alphanumeric, Distribution, StandardUniform},
+ distr::{Alphanumeric, Distribution, SampleString, StandardUniform},
prelude::StdRng,
};
use std::ops::Range;
+use std::sync::Arc;
/// Creates an random (but fixed-seeded) array of a given size and null density
pub fn create_primitive_array<T>(size: usize, null_density: f32) ->
PrimitiveArray<T>
@@ -871,3 +873,77 @@ pub fn create_f64_array_with_seed(size: usize,
nan_density: f32, seed: u64) -> F
})
.collect()
}
+
+/// Create a FixedSizeList array of primitive values
+///
+/// Arguments:
+/// - `size`: number of fixed-size lists in the array
+/// - `null_density`: density of nulls in the fixed-size list array (row-level
nulls)
+/// - `value_null_density`: density of nulls in the primitive values inside
each list
+/// - `list_size`: fixed size of each list element
+pub fn create_primitive_fixed_size_list_array<T>(
+ size: usize,
+ null_density: f32,
+ value_null_density: f32,
+ list_size: i32,
+) -> FixedSizeListArray
+where
+ T: ArrowPrimitiveType,
+ StandardUniform: Distribution<T::Native>,
+{
+ let mut rng = seedable_rng();
+ let list_size_usize = usize::try_from(list_size).expect("list_size must be
non-negative");
+ let values: PrimitiveArray<T> = (0..size * list_size_usize)
+ .map(|_| {
+ if rng.random::<f32>() < value_null_density {
+ None
+ } else {
+ Some(rng.random())
+ }
+ })
+ .collect();
+ let field = Arc::new(Field::new("item", T::DATA_TYPE, value_null_density >
0.0));
+ let nulls = (null_density > 0.0).then(|| {
+ NullBuffer::new(arrow_buffer::BooleanBuffer::collect_bool(size, |_| {
+ rng.random::<f32>() >= null_density
+ }))
+ });
+ FixedSizeListArray::new(field, list_size, Arc::new(values), nulls)
+}
+
+/// Create a Map array with string keys and primitive values
+///
+/// Arguments:
+/// - `size`: number of map entries in the array
+/// - `null_density`: density of nulls in the map array (row-level nulls)
+/// - `max_map_size`: maximum number of key-value pairs per map entry
+/// (actual size is random between 0 and max_map_size)
+/// - `key_len`: length of each random string key
+pub fn create_string_map_array<T>(
+ size: usize,
+ null_density: f32,
+ max_map_size: usize,
+ key_len: usize,
+) -> MapArray
+where
+ T: ArrowPrimitiveType,
+ StandardUniform: Distribution<T::Native>,
+{
+ let mut rng = seedable_rng();
+ let mut builder = MapBuilder::new(None, StringBuilder::new(),
PrimitiveBuilder::<T>::new());
+ for _ in 0..size {
+ if rng.random::<f32>() < null_density {
+ builder.append(false).unwrap();
+ } else {
+ let n = rng.random_range(0..=max_map_size);
+ for _ in 0..n {
+ builder
+ .keys()
+ .append_value(Alphanumeric.sample_string(&mut rng,
key_len));
+ builder.values().append_value(rng.random());
+ }
+ builder.append(true).unwrap();
+ }
+ }
+ builder.finish()
+}