use std::{hint::black_box, sync::Arc};
use arrow::{
array::{ArrayRef, FixedSizeListArray, Int32Array, ListArray, ListViewArray},
buffer::{NullBuffer, OffsetBuffer, ScalarBuffer},
datatypes::{DataType, Field},
};
use criterion::{Criterion, criterion_group, criterion_main};
use datafusion_functions_nested::reverse::array_reverse_inner;
fn array_reverse(array: &ArrayRef) -> ArrayRef {
black_box(array_reverse_inner(std::slice::from_ref(array)).unwrap())
}
fn criterion_benchmark(c: &mut Criterion) {
let number_of_arrays = 1000;
let sizes = (0..number_of_arrays)
.map(|i| 100 + i * 100)
.collect::<Vec<i32>>();
let total_values = sizes.iter().sum::<i32>();
let offsets = sizes
.iter()
.scan(0, |acc, &x| {
let offset = *acc;
*acc += x;
Some(offset)
})
.collect::<Vec<i32>>();
let offsets = ScalarBuffer::from(offsets);
let nulls = (0..number_of_arrays)
.map(|i| i % 10 != 0)
.collect::<Vec<bool>>();
let values = (0..total_values).collect::<Vec<i32>>();
let values = Arc::new(Int32Array::from(values));
let nulls_list_array = Some(NullBuffer::from(
nulls[..((number_of_arrays as usize) - 1)].to_vec(),
));
let list_array: ArrayRef = Arc::new(ListArray::new(
Arc::new(Field::new("a", DataType::Int32, false)),
OffsetBuffer::new(offsets.clone()),
values.clone(),
nulls_list_array,
));
let nulls_list_view_array = Some(NullBuffer::from(
nulls[..(number_of_arrays as usize)].to_vec(),
));
let list_view_array: ArrayRef = Arc::new(ListViewArray::new(
Arc::new(Field::new("a", DataType::Int32, false)),
offsets,
ScalarBuffer::from(sizes),
values.clone(),
nulls_list_view_array,
));
c.bench_function("array_reverse_list", |b| {
b.iter(|| array_reverse(&list_array))
});
c.bench_function("array_reverse_list_view", |b| {
b.iter(|| array_reverse(&list_view_array))
});
let array_len = 1000;
let num_arrays = 5000;
let total_values = num_arrays * array_len;
let values = (0..total_values).collect::<Vec<i32>>();
let values = Arc::new(Int32Array::from(values));
let nulls = (0..num_arrays).map(|i| i % 10 != 0).collect::<Vec<bool>>();
let nulls = Some(NullBuffer::from(nulls));
let fixed_size_list_array: ArrayRef = Arc::new(FixedSizeListArray::new(
Arc::new(Field::new("a", DataType::Int32, false)),
array_len,
values.clone(),
nulls.clone(),
));
c.bench_function("array_reverse_fixed_size_list", |b| {
b.iter(|| array_reverse(&fixed_size_list_array))
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);