Skip to content

bench: cover dictionary hash cache workloads - #27246

Closed
Rich-T-kid wants to merge 1 commit into
apache:mainfrom
Rich-T-kid:rich-T-kid/dictionary-group-values-cache-benchmarks
Closed

Rich-T-kid wants to merge 1 commit into
apache:mainfrom
Rich-T-kid:rich-T-kid/dictionary-group-values-cache-benchmarks

Conversation

@Rich-T-kid

@Rich-T-kid Rich-T-kid commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Follow-up to #26826.

Rationale for this change

Adds the benchmark cases requested in this review thread. They are kept separate so the runtime change in #26826 stays focused.

What changes are included in this PR?

Extends dictionary_group_values with cases that cover:

  • alternating 100K-value dictionaries between batches, with and without an additional Int32 group key
  • one large dictionary values array shared by every batch
  • a fresh 20-value dictionary per batch, matching dictionaries produced by a projection cast

The existing cases are unchanged. There are no runtime code changes.

What is the testing strategy for this PR?

Each new benchmark runs in Criterion test mode.

Are there any user-facing changes?

No.

@github-actions github-actions Bot added the physical-plan Changes to the physical-plan crate label Nov 8, 2026
@Rich-T-kid
Rich-T-kid force-pushed the rich-T-kid/dictionary-group-values-cache-benchmarks branch from 289a4b0 to 4c510c0 Compare November 8, 2026 18:30
@Rich-T-kid
Rich-T-kid marked this pull request as ready for review November 8, 2026 19:19
@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

cc @jayzhan211 🙇

@adriangbot

Copy link
Copy Markdown

Benchmark for this request failed before finishing (Kubernetes reason: BackoffLimitExceeded).

Benchmarks requested: tpch

Runner log (last 40 lines)
2026-11-12T15:38:47.395789Z  INFO runner starting benchmark runner bench_type=Datafusion, pr_url=https://github.com/apache/datafusion/pull/27246, benchmarks=tpch
2026-11-12T15:38:47.470940Z  INFO benchmark_controller::runner::bench_datafusion === Cloning PR branch ===
2026-11-12T15:38:47.470961Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["clone", "--depth=200", "https://github.com/apache/datafusion.git", "/workspace/datafusion-branch"], cwd="/"
2026-11-12T15:38:57.481351Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin", "refs/pull/27246/head:rich-T-kid/dictionary-group-values-cache-benchmarks", "main"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:02.482828Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["checkout", "rich-T-kid/dictionary-group-values-cache-benchmarks"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:07.485159Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["merge-base", "HEAD", "origin/main"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:12.487356Z  INFO benchmark_controller::runner::bench_datafusion === Checking out custom changed ref === changed_ref=e19b54c40917e3fad70a2743fc79881a0be43da3
2026-11-12T15:39:12.487371Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin", "refs/pull/27246/head"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:17.488875Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:22.491429Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["-c", "advice.detachedHead=false", "checkout", "e19b54c40917e3fad70a2743fc79881a0be43da3"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:27.492780Z ERROR runner benchmark failed error=git checkout: git -c advice.detachedHead=false checkout e19b54c40917e3fad70a2743fc79881a0be43da3 exited with code 128
stdout:

stderr:
fatal: reference is not a tree: e19b54c40917e3fad70a2743fc79881a0be43da3
Kubernetes message
Job has reached the specified backoff limit

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

Benchmark for this request failed before finishing (Kubernetes reason: BackoffLimitExceeded).

Benchmarks requested: tpcds

Runner log (last 40 lines)
2026-11-12T15:38:51.918618Z  INFO runner starting benchmark runner bench_type=Datafusion, pr_url=https://github.com/apache/datafusion/pull/27246, benchmarks=tpcds
2026-11-12T15:38:51.980170Z  INFO benchmark_controller::runner::bench_datafusion === Cloning PR branch ===
2026-11-12T15:38:51.980191Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["clone", "--depth=200", "https://github.com/apache/datafusion.git", "/workspace/datafusion-branch"], cwd="/"
2026-11-12T15:38:56.990270Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin", "refs/pull/27246/head:rich-T-kid/dictionary-group-values-cache-benchmarks", "main"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:01.992747Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["checkout", "rich-T-kid/dictionary-group-values-cache-benchmarks"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:06.994748Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["merge-base", "HEAD", "origin/main"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:11.999001Z  INFO benchmark_controller::runner::bench_datafusion === Checking out custom changed ref === changed_ref=e19b54c40917e3fad70a2743fc79881a0be43da3
2026-11-12T15:39:11.999017Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin", "refs/pull/27246/head"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:17.001573Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:22.003250Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["-c", "advice.detachedHead=false", "checkout", "e19b54c40917e3fad70a2743fc79881a0be43da3"], cwd="/workspace/datafusion-branch"
2026-11-12T15:39:27.005550Z ERROR runner benchmark failed error=git checkout: git -c advice.detachedHead=false checkout e19b54c40917e3fad70a2743fc79881a0be43da3 exited with code 128
stdout:

stderr:
fatal: reference is not a tree: e19b54c40917e3fad70a2743fc79881a0be43da3
Kubernetes message
Job has reached the specified backoff limit

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

Benchmark for this request failed before finishing (Kubernetes reason: BackoffLimitExceeded).

Benchmarks requested: clickbench_partitioned

Runner log (last 40 lines)
2026-11-12T15:39:50.816275Z  INFO runner starting benchmark runner bench_type=Datafusion, pr_url=https://github.com/apache/datafusion/pull/27246, benchmarks=clickbench_partitioned
2026-11-12T15:39:50.867521Z  INFO benchmark_controller::runner::bench_datafusion === Cloning PR branch ===
2026-11-12T15:39:50.867542Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["clone", "--depth=200", "https://github.com/apache/datafusion.git", "/workspace/datafusion-branch"], cwd="/"
2026-11-12T15:40:00.873138Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin", "refs/pull/27246/head:rich-T-kid/dictionary-group-values-cache-benchmarks", "main"], cwd="/workspace/datafusion-branch"
2026-11-12T15:40:05.876115Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["checkout", "rich-T-kid/dictionary-group-values-cache-benchmarks"], cwd="/workspace/datafusion-branch"
2026-11-12T15:40:10.877490Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["merge-base", "HEAD", "origin/main"], cwd="/workspace/datafusion-branch"
2026-11-12T15:40:15.879710Z  INFO benchmark_controller::runner::bench_datafusion === Checking out custom changed ref === changed_ref=e19b54c40917e3fad70a2743fc79881a0be43da3
2026-11-12T15:40:15.879725Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin", "refs/pull/27246/head"], cwd="/workspace/datafusion-branch"
2026-11-12T15:40:20.881268Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["fetch", "origin"], cwd="/workspace/datafusion-branch"
2026-11-12T15:40:25.883783Z  INFO benchmark_controller::runner::shell running command cmd=git, args=["-c", "advice.detachedHead=false", "checkout", "e19b54c40917e3fad70a2743fc79881a0be43da3"], cwd="/workspace/datafusion-branch"
2026-11-12T15:40:30.886110Z ERROR runner benchmark failed error=git checkout: git -c advice.detachedHead=false checkout e19b54c40917e3fad70a2743fc79881a0be43da3 exited with code 128
stdout:

stderr:
fatal: reference is not a tree: e19b54c40917e3fad70a2743fc79881a0be43da3
Kubernetes message
Job has reached the specified backoff limit

File an issue against this benchmark runner

@Rich-T-kid
Rich-T-kid marked this pull request as draft November 12, 2026 15:54
Surajsuthar pushed a commit to Surajsuthar/datafusion that referenced this pull request Nov 14, 2026
…6826)

## Which issue does this PR close?

Closes apache#26812.

## Rationale for this change

Dictionary batches often share one values array while only their keys
change. Partial aggregation was rehashing the same dictionary values for
every batch.

## What changes are included in this PR?

The non-streaming group table now caches dictionary value hashes while
the values `Arc` is unchanged. A single dictionary group key can also
map known keys directly to group indices.

```text
Dictionary batch
       |
       v
single dictionary column + complete cached mapping?
       | yes                              | no
       v                                  v
keys -> cached group IDs           per-column hashing
                                   |                 |
                            eligible dictionary   fallback
                                   |                 |
                          cached value hashes   hash column
                                   |                 |
                          scatter through keys -----+
                                   |
                                   v
                         hash/equality group lookup
```

New keys, changed or oversized dictionaries, and partial emission use
the normal fallback. Multi-column hashing keeps the same semantics as
`create_hashes`. The benchmark fixtures are split into apache#27246.

## What is the testing strategy for this PR?

Unit tests cover cached and uncached hash consistency, unseen keys,
changed dictionaries, null groups, partial emission, and forced
collisions.

Hosted cases from apache#27246 show [alternating
dictionary-only](apache#26826 (comment))
1.30× faster; [alternating dictionary +
Int32](apache#26826 (comment))
and [fresh
dictionaries](apache#26826 (comment))
flat; and [shared dictionary +
Int32](apache#26826 (comment))
1.14× faster at 32K values and 1.28× at 100K.

Exact-head hosted suites with RLE dictionary reads enabled on both
sides:

-
[TPC-H](apache#27249 (comment)):
796.01 → 799.79 ms (0.5% higher).
-
[TPC-DS](apache#27249 (comment)):
9.02 → 8.88 s (1.6% lower).
-
[ClickBench](apache#27249 (comment)):
38.26 → 38.16 s (0.3% lower).

## Are there any user-facing changes?

No.

---------

Co-authored-by: Jay Zhan <[email protected]>
@Rich-T-kid Rich-T-kid closed this Nov 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

physical-plan Changes to the physical-plan crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants