You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/09/15 12:01:52 UTC
(datafusion) 01/01: bench: cover dictionary group keys with a shared values array (#25198)
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-25198-b376290aad68bac68010234cd25fcfcfbc92d6d2
in repository https://gitbox.apache.org/repos/asf/datafusion.git
commit 7917a9a65a0343a6b5536299de5482a899d77c51
Author: Lía Adriana <li...@datadoghq.com>
AuthorDate: Tue Sep 15 12:01:28 2026 +0000
bench: cover dictionary group keys with a shared values array (#25198)
## Which issue does this PR close?
[Related to #24822. No issue
closed.](https://github.com/apache/datafusion/pull/25185)
## Rationale for this change
The benchmarks in this file build a fresh values array per batch and cap
cardinality at the batch size. Neither shape matches a real plan: `take`
and `filter` clone the values `Arc` and rewrite only the keys, so
batches downstream of a repartition share one values array, and because
it is never compacted its cardinality can far exceed the rows in a
batch. Per-batch work that scales with dictionary cardinality is
invisible under the current parameters.
## What changes are included in this PR?
Adds `bench_shared_values_arc`: 32 batches of 8192 rows sharing one
values array, at cardinalities 8192, 100k and 500k.
## What is the testing strategy for this PR?
Benchmark-only. Ran the bench locally and `cargo clippy --all-targets -D
warnings`.
## Are there any user-facing changes?
No
---
.../benches/dictionary_group_values.rs | 74 +++++++++++++++++++++-
1 file changed, 73 insertions(+), 1 deletion(-)
diff --git a/datafusion/physical-plan/benches/dictionary_group_values.rs b/datafusion/physical-plan/benches/dictionary_group_values.rs
index e0cbc3577c..502869787e 100644
--- a/datafusion/physical-plan/benches/dictionary_group_values.rs
+++ b/datafusion/physical-plan/benches/dictionary_group_values.rs
@@ -247,11 +247,83 @@ fn bench_take_n(c: &mut Criterion) {
group.finish();
}
+/// Batches that share one dictionary values array, as produced downstream of
+/// a repartition or filter: `take`/`filter` clone the values `Arc` and rewrite
+/// only the keys, so the values array is never compacted and its cardinality
+/// reflects the whole upstream stream rather than a single batch.
+///
+/// The other benchmarks here always allocate a fresh values array per batch
+/// and cap cardinality at the batch size, so neither the `Arc` reuse nor the
+/// `cardinality >> rows` regime is covered by them.
+fn bench_shared_values_arc(c: &mut Criterion) {
+ // More batches than `N_BATCHES`: the cost this exercises is paid once per
+ // batch, so a longer run per values array is what a real partition looks
+ // like (thousands of batches sharing one dictionary).
+ const BATCHES: usize = 32;
+
+ let mut group = c.benchmark_group("dict_shared_values_arc");
+ let size = SIZES[0];
+
+ for &cardinality in &[size, 32 * 1024, 64 * 1024, 100_000, 500_000] {
+ // Seeded per cardinality so each configuration is reproducible on its
+ // own and adding one does not change the data used by the others.
+ let mut rng = StdRng::seed_from_u64(SEED);
+ // One values array, shared by every batch.
+ let strings: Vec<String> =
+ (0..cardinality).map(|i| format!("v_{i:08}")).collect();
+ let values: ArrayRef = Arc::new(StringArray::from(
+ strings.iter().map(|s| Some(s.as_str())).collect::<Vec<_>>(),
+ ));
+
+ let batches: Vec<ArrayRef> = (0..BATCHES)
+ .map(|_| {
+ let keys: Vec<i32> = (0..size)
+ .map(|_| rng.random_range(0..cardinality) as i32)
+ .collect();
+ Arc::new(DictionaryArray::<Int32Type>::new(
+ PrimitiveArray::<Int32Type>::from(keys),
+ Arc::clone(&values),
+ )) as ArrayRef
+ })
+ .collect();
+
+ let schema = dict_schema();
+ group.throughput(Throughput::Elements((size * BATCHES) as u64));
+ group.bench_function(
+ BenchmarkId::new(
+ "shared_values_arc",
+ format!("size_{size}_card_{cardinality}"),
+ ),
+ |b| {
+ b.iter_batched_ref(
+ || {
+ (
+ new_group_values(schema.clone(), &GroupOrdering::None)
+ .unwrap(),
+ Vec::<usize>::with_capacity(size),
+ )
+ },
+ |(gv, groups)| {
+ for arr in &batches {
+ gv.intern(std::slice::from_ref(arr), groups).unwrap();
+ black_box(&*groups);
+ }
+ black_box(gv.emit(EmitTo::All).unwrap());
+ },
+ BatchSize::SmallInput,
+ );
+ },
+ );
+ }
+ group.finish();
+}
+
criterion_group!(
benches,
bench_intern_emit,
bench_repeated_intern_emit,
bench_scalar_append_equal,
- bench_take_n
+ bench_take_n,
+ bench_shared_values_arc
);
criterion_main!(benches);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org