Skip to content

Reuse sort-key storage across rejected GROUP BY candidates - #19534

Open
xiangfu0 wants to merge 1 commit into
apache:masterfrom
xiangfu0:xiangfu0/java-groupby-topk-allocation
Open

xiangfu0 wants to merge 1 commit into
apache:masterfrom
xiangfu0:xiangfu0/java-groupby-topk-allocation

Conversation

@xiangfu0

@xiangfu0 xiangfu0 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

GROUP BY top-K trimming allocates sort-key arrays and intermediate wrappers for rejected candidates. Reuse that storage across consecutive rejections; create a wrapper with the current key/record when a candidate is admitted. Immediate admissions retain the existing path, including comparator, tie handling and output order. An admitted row's sort-key array is never subsequently overwritten.

Reproduction and benchmark

Select top K from a deterministic prepared map of numeric group results. Small/large K retain 20/5,000 of 8,192 groups; the large-N case retains 5,000 of 100,000. Best-first rejects every later candidate; worst-first admits every later candidate. Full-sort/no-trim retain all 8,192 with/without sorting, and unsorted top-K retains 5,000 without ordering the output. Timing includes construction of TableResizer, ORDER BY extraction, heap maintenance and optional output sorting; it excludes input-map preparation, SQL parsing, scanning, aggregation, JNI and transport.

Measured against upstream 5771d6acea60cd72738116835111cf7c49965373 on an Apple M2 Max (12 cores, 32 GiB), macOS ARM64 and Temurin JDK 25. Three AB/BA/AB pairs, one fresh JMH fork per case/arm, one thread, 512 MiB heap, three 500 ms warmups and five 500 ms measurements, with GC profiling. Both arms use the same pinned runtime and measurement code; only the TableResizer class family differs. Sorted classpath order and runtime hashes were checked. The workstation was shared, with no task builds or other task benchmarks during timing.

Results

Times and allocations are medians of three arm means. Ratios are medians of paired baseline/candidate time ratios; ranges retain all three pairs. Values above 1 favor the candidate.

Scenario Baseline us/op Candidate us/op Paired ratio Pair range Allocation B/op before -> after Reduction
FULL_SORT 1357.213 1348.913 1.002x 0.968-1.019 491307 -> 491307 0.0%
LARGE_K_BEST_FIRST 684.138 675.338 1.012x 1.001-1.013 357073 -> 280489 21.4%
LARGE_K_RANDOM 1456.872 1457.745 0.995x 0.990-1.016 433692 -> 410004 5.5%
LARGE_K_WORST_FIRST 1091.692 1080.635 1.010x 0.997-1.053 433687 -> 433687 0.0%
LARGE_N_RANDOM 7392.171 6354.504 1.160x 1.156-1.163 4840558 -> 1234591 74.5%
NO_TRIM 0.091 0.092 0.998x 0.923-1.034 384 -> 384 0.0%
SMALL_K_BEST_FIRST 78.667 63.169 1.245x 1.158-1.316 197705 -> 1601 99.2%
SMALL_K_RANDOM 188.672 84.294 2.259x 2.217-2.310 393835 -> 10697 97.3%
SMALL_K_WORST_FIRST 288.432 297.038 0.971x 0.966-0.994 393836 -> 393836 0.0%
UNSORTED_TOP_K 613.472 605.108 1.027x 0.978-1.084 433681 -> 409992 5.5%

The small-K all-admitted case is about 3% slower with unchanged allocation; large-K random has a 0.995× median ratio. The no-trim control includes a 0.923× individual pair despite its 0.998× median. These non-wins remain part of the result. This is a controlled component comparison, not packaged deployment throughput or proof that every query benefits.

Validation

Recorded local validation: 81 tests passed—13 table-resizer, 9 indexed-table, 3 deterministic-indexed-table, 12 sorted-combine and 44 inter-segment GROUP BY tests. Regression coverage includes rejection runs, immediate admissions, exact identities/order, ties, both resize directions, nulls/NaN/signed zero and aggregate-state ownership. Every measurement fork validated complete result membership, uniqueness, ordering, record identity and input preservation against an independent oracle before timing.

Normal compilation/tests, Spotless, Checkstyle and license format/check passed. Independent correctness, testing and performance reviews found no actionable issues. Scoped lint reported no source warnings and four existing dependency-manifest path warnings. Full-reactor Xlint was not repeated after the same-base attempt failed in unchanged Zstandard code on a missing JetBrains annotation.

@xiangfu0 xiangfu0 added the performance Related to performance optimization label Sep 12, 2026
@codecov-commenter

codecov-commenter commented Sep 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.72%. Comparing base (5771d6a) to head (e597d09).

Additional details and impacted files
@@            Coverage Diff            @@
##             master   #19534   +/-   ##
=========================================
  Coverage     67.72%   67.72%           
  Complexity     1450     1450           
=========================================
  Files          3490     3490           
  Lines        225032   225043   +11     
  Branches      35527    35530    +3     
=========================================
+ Hits         152393   152406   +13     
+ Misses        60612    60608    -4     
- Partials      12027    12029    +2     
Flag Coverage Δ
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-25 67.72% <100.00%> (+<0.01%) ⬆️
lane-a 100.00% <ø> (ø)
lane-b 0.00% <ø> (ø)
temurin 67.72% <100.00%> (+<0.01%) ⬆️
unittests 67.72% <100.00%> (+<0.01%) ⬆️
unittests1 57.83% <100.00%> (+0.02%) ⬆️
unittests2 39.48% <0.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Rows rejected by GROUP BY top-K trimming still allocate sort-key storage and wrappers. Reuse scratch across consecutive rejections while preserving ownership of admitted rows, comparator behavior and result ordering.
@xiangfu0
xiangfu0 force-pushed the xiangfu0/java-groupby-topk-allocation branch from f4ee8ea to e597d09 Compare September 12, 2026 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Related to performance optimization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants