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-24078-597170e925f174040f0c95ecb8d673a6642796df in repository https://gitbox.apache.org/repos/asf/datafusion.git
commit 9114e78953bad29dc0acf5ba230a8b839b1fe605 Author: JS <[email protected]> AuthorDate: Tue Aug 4 19:28:06 2026 +0200 bench: add ArrowBytesMap benchmarks (#24078) ## Which issue does this PR close? - Refs #13867. ## Rationale for this change This adds a focused, reproducible microbenchmark for `ArrowBytesMap` so that proposed implementation changes can be measured against `main` using the same workloads. The benchmark is intentionally separated from the optimization, as requested during review. ## What changes are included in this PR? - Register a Criterion benchmark target for `datafusion-physical-expr-common`. - Add workloads covering: - unique 4-byte values; - unique 32-byte values; - 32-byte values with low cardinality. This PR changes measurement coverage only. It does not change the `ArrowBytesMap` implementation or runtime behavior. ## Are these changes tested? Yes. The benchmark was previously compiled and run on Ubuntu 24.04 under WSL2 as part of the measurements in the original combined PR. The following checks were also previously run against these exact benchmark files: - `cargo fmt --all --check` - `cargo clippy --all-targets --all-features -- -D warnings` - `cargo test -p datafusion-physical-expr-common --all-features` - `cargo test -p datafusion-physical-plan group_values` No commands were rerun for this history-only split. ## Are there any user-facing changes? No. --- datafusion/physical-expr-common/Cargo.toml | 4 ++ .../benches/arrow_bytes_map.rs | 82 ++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/datafusion/physical-expr-common/Cargo.toml b/datafusion/physical-expr-common/Cargo.toml index d1ee7feb29..903f5a6a90 100644 --- a/datafusion/physical-expr-common/Cargo.toml +++ b/datafusion/physical-expr-common/Cargo.toml @@ -65,3 +65,7 @@ rand = { workspace = true } [[bench]] harness = false name = "compare_nested" + +[[bench]] +harness = false +name = "arrow_bytes_map" diff --git a/datafusion/physical-expr-common/benches/arrow_bytes_map.rs b/datafusion/physical-expr-common/benches/arrow_bytes_map.rs new file mode 100644 index 0000000000..7c8cdc3b4c --- /dev/null +++ b/datafusion/physical-expr-common/benches/arrow_bytes_map.rs @@ -0,0 +1,82 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +use arrow::array::{ArrayRef, StringArray}; +use criterion::{Criterion, Throughput, criterion_group, criterion_main}; +use datafusion_physical_expr_common::binary_map::{ArrowBytesMap, OutputType}; +use std::hint::black_box; +use std::sync::Arc; + +const NUM_ROWS: usize = 8192; + +fn make_short_strings(cardinality: usize) -> ArrayRef { + let values = (0..NUM_ROWS).map(|index| format!("{:04x}", index % cardinality)); + Arc::new(StringArray::from_iter_values(values)) +} + +fn make_long_strings(cardinality: usize) -> ArrayRef { + let values = (0..NUM_ROWS).map(|index| { + let value = (index % cardinality) as u32; + format!( + "{value:08x}{:08x}{:08x}{:08x}", + value.wrapping_mul(17), + value.wrapping_mul(31), + value.wrapping_mul(127) + ) + }); + Arc::new(StringArray::from_iter_values(values)) +} + +fn bench_arrow_bytes_map(c: &mut Criterion) { + let cases = [ + // Exercises inline entry storage while still growing the output buffer. + ("short_unique", make_short_strings(NUM_ROWS)), + // Exercises repeated buffer growth and out-of-line entry storage. + ("long_unique", make_long_strings(NUM_ROWS)), + // Fits the distinct values in the initial buffer and repeats comparisons. + ("long_low_cardinality", make_long_strings(128)), + ]; + + let mut group = c.benchmark_group("arrow_bytes_map"); + group.throughput(Throughput::Elements(NUM_ROWS as u64)); + + for (name, values) in cases { + group.bench_function(name, |b| { + b.iter(|| { + let mut map = ArrowBytesMap::<i32, usize>::new(OutputType::Utf8); + let mut next_payload = 0; + map.insert_if_new( + &values, + |_| { + let payload = next_payload; + next_payload += 1; + payload + }, + |payload| { + black_box(payload); + }, + ); + black_box(map.into_state()) + }) + }); + } + + group.finish(); +} + +criterion_group!(benches, bench_arrow_bytes_map); +criterion_main!(benches); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
