perf(relational): coordinate validation rides the aggregate already running - #357
Merged
Merged
Conversation
…unning
`check_coordinates_single_valued` ran one `group_by(d)` **per declared
coordinate**, and because the frame is a lazy scan over the caller's index, each
`collect()` re-opened and re-parsed the source. Four coordinates meant four
passes and four reads of the same file.
`_explicit_dim_frame` — the only caller — already groups by `d` over that frame
to build `(val, ord, coordinates…)`. So the `n_unique` counts now ride in that
aggregate and the check reads them out of the result. Zero extra passes, and one
collect where there were N + 1.
Measured on a 200k-label index with four coordinates, minimum of five builds,
three alternating rounds:
folded 0.0378 0.0386 0.0408
before 0.0645 0.0676 0.0681
~1.75x on that step, and repeatable rather than inside the noise — the second
cost the issue named, the re-read, is what makes it more than the polish it was
filed as.
It also fixes a usability bug the loop had: raising on the first offending
coordinate meant a source with two bad ones was fixed, rebuilt, and refused
again. Every offender is named now, which is free once the counts arrive in one
frame — `test_every_multi_valued_coordinate_is_named_at_once`.
Closes #273
FBumann
enabled auto-merge (squash)
July 30, 2026 14:16
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughCoordinate validation now computes all coordinate uniqueness counts during the existing dimension aggregation. The validator consumes those counts and reports every multi-valued coordinate in one ChangesCoordinate validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Closes #273.
check_coordinates_single_valuedran onegroup_by(d)per declared coordinate, and because the frame is a lazy scan over the caller's index, eachcollect()re-opened and re-parsed the source. Four coordinates meant four passes and four reads of the same file.The fix is the issue's own "better still"
_explicit_dim_frameis the only caller, and it already groups bydover that same frame to build(val, ord, coordinates…). Then_uniquecounts now ride in that aggregate and the check reads them out of the result:Zero extra passes, and one collect where there were N + 1.
Measured
200k-label index with four coordinates, minimum of five builds, three alternating rounds:
~1.75x on that step, and repeatable rather than inside the noise — which is worth stating given how noisy this machine has been on smaller numbers. The re-read is what makes this more than the polish the issue was filed as; index sources are dim-sized, but re-parsing a parquet file per coordinate is not.
A usability bug went with it
The loop raised on the first offending coordinate, so a source with two bad ones was fixed, rebuilt, and refused again. Every offender is named now, which is free once the counts arrive in one frame:
test_every_multi_valued_coordinate_is_named_at_oncepins it.This landed cheaply because #355 had just isolated these checks into
relational/data_validation.pyas pure functions, and #354's parity table pins the verdicts from outside — so the optimisation could not quietly change what gets refused.Verified
700 passed, 4 skipped, 1 xfailed.
ruff check,ruff format --check,pyrefly check(0 errors). Built in a git worktree.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests