SubhamSinghal opened a new pull request, #25468:
URL: https://github.com/apache/datafusion/pull/25468

   ## Which issue does this PR close?
   
   Part of the `enable_window_topn` work (#13586).
   
   ## Rationale for this change
   
   Profiling `PartitionedTopKDenseRank` (`/usr/bin/sample`, 10M-row fixture,
   100K partitions) showed two costs that dominate the operator, neither of
   which is inherent to DENSE_RANK semantics:
   
   1. **Emit was 61% of busy samples**, 87% of it in one tiny
      `take_record_batch` per `GroupEntry` plus the coalescer copy that
      follows. A `GroupEntry` holds only the rows one source batch
      contributed at one ob value, so with P partitions, K distinct ob
      values and B contributing batches there are up to P x K x B of them.
      `TopKHeap::emit_with_state` already solves this exact shape with a
      single `interleave_record_batch`; DENSE_RANK just wasn't using it.
   
   2. **`size()` was 8.3% self-time.** `DenseRankPartitionState::size()`
      walked every group and every entry in every partition, and `size()`
      is called once per `insert_batch` to resize the reservation — so the
      walk costs O(entries) per batch. `TopKHeap` already avoids this with
      a running `owned_bytes` total.
   
   ## What changes are included in this PR?
   
   Two commits, both internal to `PartitionedTopKDenseRank`:
   
   - **emit**: gather retained rows with `interleave_record_batch`, chunked
     at `batch_size` so the operator emits the same batch sizes as before
     and never materializes all retained rows at once. Pairs are pushed in
     emit order (partitions sorted, ob ascending, entries in insertion
     order), so the output needs no post-sort.
   - **size**: `DenseRankPartitionState` gains a `contents_bytes` running
     total, maintained at the four mutation sites (append to an existing ob
     group, insert with room, evict-then-insert, and the buffer growth each
     can trigger).
   
   No signature, plan-shape, config or semantic change. `PartitionedTopK`
   and `PartitionedTopKRank` are untouched.
   
   ## Are these changes tested?
   
   Yes.
   
   - 91 `topk` + 42 `partitioned_topk` unit tests, `window_topn.slt`,
     `dev/rust_lint.sh` (fmt + clippy) all pass.
   - New `test_partitioned_topk_dense_rank_contents_bytes_tracks_recompute`
     asserts the incremental total against a full recompute **after every
     batch** across 64 randomized shapes, reusing the `DiffShape` harness
     from the correctness differential test. It asserts the workload
     actually evicted, so the eviction case can't silently go unchecked.
     Mutation-checked: zeroing one term in the eviction charge fails this
     test and no other.
   - Emit order is **byte-identical** to before at `target_partitions = 1`
     (this matters — `PartitionedTopKExec` advertises its output ordering,
     and breaking it would either produce wrong ranks or force a SortExec
     back into the plan).
   - `count(*)` / `sum(ob)` / `sum(rn)` / `sum(pk)` digests unchanged.
   
   ## Are there any user-facing changes?
   
   Faster `DENSE_RANK() OVER (PARTITION BY ...)` top-N when
   `datafusion.optimizer.enable_window_topn` is enabled. No API change.
   
   ### Benchmarks
   
   `benchmarks/queries/h2o/window.sql` q24–q29 (the DENSE_RANK sweep), 10M-row
   `J1_1e7_1e7_NA` parquet, `dfbench h2o`, 3 reps round-robin, medians in ms.
   Both binaries `--release` from the same base in one session;
   `enable_window_topn` via `DATAFUSION_OPTIMIZER_ENABLE_WINDOW_TOPN`.
   
   | query | shape | flag off | main, flag on | branch, flag on | branch vs 
main |
   |---|---|--:|--:|--:|--:|
   | q24–q28 | 100 – 10K partitions | 191–244 | 45–65 | 44–66 | within noise |
   | q29 | 100K partitions | 193.8 | 213.1 | 149.6 | **1.42x** |
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to