Skip to content

perf: apply min-alloc split to ByteViewGroupValueBuilder::take_n (follow-up to #22165)#22205

Closed
RyanJamesStewart wants to merge 1 commit into
apache:mainfrom
RyanJamesStewart:perf/take_n-reclaim-capacity
Closed

perf: apply min-alloc split to ByteViewGroupValueBuilder::take_n (follow-up to #22165)#22205
RyanJamesStewart wants to merge 1 commit into
apache:mainfrom
RyanJamesStewart:perf/take_n-reclaim-capacity

Conversation

@RyanJamesStewart
Copy link
Copy Markdown
Contributor

@RyanJamesStewart RyanJamesStewart commented May 15, 2026

Which issue does this PR close?

Follow-up to #22165 / #22164.

Rationale for this change

#22165 introduced the split_vec_min_alloc helper and applied it to the take_n paths in bytes.rs and primitive.rs, but did not cover the byte-view builder. ByteViewGroupValueBuilder::take_n_inner still used self.views.drain(0..n).collect::<Vec<_>>(), which always allocates n elements and leaves the retained vec at its pre-emit capacity.

Under an OOM-triggered EmitTo::First(n) emit, n is close to the length of views, so this copies the largest allocation — exactly the case #22164 was filed to fix. This PR routes the byte-view builder through the same split_vec_min_alloc helper, which allocates min(n, len - n) instead, so all three multi-group-by builders now share one strategy.

This PR previously also modified bytes.rs and primitive.rs; those changes are now fully covered by #22165 and have been dropped. The PR is rebased onto current main and reduced to the one builder #22165 missed.

What changes are included in this PR?

ByteViewGroupValueBuilder::take_n_inner: replace drain(0..n).collect() with split_vec_min_alloc(&mut self.views, n).

Are these changes tested?

Behavior is unchanged. Existing test_byte_view_take_n and test_byte_view_take_n_partial_completed_nonzero_index exercise both the drain and split_off branches of the helper; all take_n tests pass locally.

Are there any user-facing changes?

No.

@github-actions github-actions Bot added the physical-plan Changes to the physical-plan crate label May 15, 2026
Follow-up to apache#22165, which replaced `drain(0..n).collect()` with the
`split_vec_min_alloc` helper in the `bytes.rs` and `primitive.rs`
`take_n` paths but did not cover the byte-view builder.

`ByteViewGroupValueBuilder::take_n_inner` had the same idiom on
`self.views`: `drain(0..n).collect()` always allocates `n` elements
and leaves the retained vec at its pre-emit capacity. Under an
OOM-triggered `EmitTo::First(n)` emit, `n` is close to `len`, so this
copies the largest allocation. Routing through `split_vec_min_alloc`
allocates `min(n, len - n)` instead, matching the other builders.

Behavior is unchanged; existing `test_byte_view_take_n` /
`test_byte_view_take_n_partial_completed_nonzero_index` cover both
the drain and split_off branches.
@RyanJamesStewart RyanJamesStewart force-pushed the perf/take_n-reclaim-capacity branch from e94d307 to e4a184a Compare May 21, 2026 12:24
@RyanJamesStewart RyanJamesStewart changed the title perf: reclaim capacity in take_n during OOM-triggered partial-aggregation emit perf: apply min-alloc split to ByteViewGroupValueBuilder::take_n (follow-up to #22165) May 21, 2026
RyanJamesStewart added a commit to RyanJamesStewart/datafusion that referenced this pull request May 21, 2026


Addresses the review on apache#22416:

- split_vec_min_alloc: shrink_to_fit the emitted prefix in the
  split_off branch. datafusion accounts memory by capacity rather
  than length, so the prefix must not retain the pre-split (larger)
  allocation's capacity.
- Remove the duplicate split_vec_min_alloc from physical-plan's
  multi_group_by/mod.rs (added in apache#22165); bytes.rs and primitive.rs
  now use the shared datafusion_common::utils version.
- Fold in the ByteViewGroupValueBuilder::take_n change previously
  proposed as apache#22205, so this PR converts every split_vec_min_alloc
  call site in one place.

All split_vec_min_alloc, take_n and min_max tests pass.
@RyanJamesStewart
Copy link
Copy Markdown
Contributor Author

Superseded by #22416, which hoists split_vec_min_alloc into datafusion_common::utils and includes this ByteViewGroupValueBuilder::take_n change alongside the other call sites and the shrink_to_fit fix on the emitted prefix. Closing in favor of that PR.

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