[PERF] NumPy prefix sums for integer conditional_join range-sum aggregations - #1673
Open
samukweku wants to merge 4 commits into
Open
[PERF] NumPy prefix sums for integer conditional_join range-sum aggregations#1673samukweku wants to merge 4 commits into
samukweku wants to merge 4 commits into
Conversation
Replace the O(sum of interval widths) Rust kernels backing join_agg(..., aggfunc=[(col, "sum")]) for the <-only, >-only, and arbitrary-interval dispatch paths with an O(n + m) NumPy prefix-sum, for integer dtypes. Float dtypes are untouched (tracked separately in #1671, since the existing float kernels use compensated summation). Also removes a pre-existing duplicate definition of _sum_starts_ends found while editing it. Issue #1648 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1gZKDRiZoBLZnXXXjW3gt
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1gZKDRiZoBLZnXXXjW3gt
Contributor
|
Repo has no existing benchmarks/ convention -- keeping the numbers reproducible in the PR description avoids introducing an uncommitted- to-CI script and a new top-level directory precedent. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1gZKDRiZoBLZnXXXjW3gt
This was referenced Aug 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
join_agg(..., aggfunc=[(col, "sum")])range aggregations. Sparse and moderately sized ranges stay on the existing
Rust kernels; dense overlapping ranges use one O(n + m) NumPy prefix sum.
of interval widths exceeds three times the aggregation-array length. Three
or fewer ranges skip estimation because they cannot cross that threshold.
<-only,>-only, and arbitrary[start:end)paths for all eightsupported integer dtypes.
tracked separately in [PERF] Use prefix sums for conditional_join range aggregations (float dtypes) #1671.
_sum_starts_endsdefinition.ELI5
Rust rereads every requested section. NumPy first writes down one running
total for the whole array. We make that extra list only when rereading all the
requested sections would mean walking the whole array more than three times.
Why adaptive dispatch
An unconditional prefix sum regresses selective joins because it scans and
copies the full aggregation array even when only one value is needed. On a
sorted one-million-row right frame with one matching row, adaptive Rust takes
4.07 ms end to end versus 6.17 ms for unconditional prefix construction.
The measured kernel crossover for one million values and 1,000 intervals is:
For a dense 20,000-by-20,000
<aggregation where every left row matches theentire right frame, adaptive prefix sums take 0.92 ms end to end versus
254.31 ms when forced through Rust, a 278x speedup.
Correctness contract
including uint64 bit reinterpretation.
reconstruction retain their existing behavior.
Test plan
pixi run pytest tests/functions/test_conditional_join_agg_int_sum.py -q— 70 passed, covering sparse/dense dispatch and all eight integer dtypes.
pixi run pytest tests/functions/test_conditional_join_agg_int_sum.py tests/functions/test_conditional_join.py -q— 311 passed, 1 skipped.
kernels across all integer dtypes and all three range shapes.
Follow-up
into Rust with a one-buffer dense path and coordinated release.
Closes #1648
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com