Repository navigation
Use a skewed intersection for very unequal array containers - #386
Open
emschwartz wants to merge 3 commits into
Open
emschwartz wants to merge 3 commits into
emschwartz wants to merge 3 commits into
Conversation
With the `simd` feature, `ArrayStore -= &ArrayStore` reserved `min(lhs.len(), rhs.len())` for its output, but a difference can hold up to `lhs.len()` values. The Vec grew to cover it, so results were correct. Reserve `lhs.len()`, as `Sub` already does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every caller reserves an upper bound for its output, so the `push` in `visit_scalar` never reallocates, but the compiler cannot see that. The scalar merge loops for `&`, `|`, `^` and `-` therefore carry a call to `grow_one` and reload the Vec's fields from the stack on each write. Asserting `len < capacity` before the push removes the call and lets the loops keep their state in registers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When one array is over 64x smaller than the other, binary searching the larger one beats a linear merge, as CRoaring does in intersect_skewed_uint16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Addresses #133. Stacked on #385: only the last commit is new, and the numbers below are measured against that PR.
When one array container is more than 64 times larger than the other,
&,&=andintersection_lennow binary search the larger one instead of merging. This follows CRoaring'sintersect_skewed_uint16, by way of saik0's 2022 port linked in the issue. It searches for four values at once so their loads overlap. A galloping search was tried first and was about 2 to 5 times slower at these sizes.Change in time over 10 interleaved runs of each binary. census1881 is the one dataset with many skewed pairs.
and_skewedis a new bench of 10 or 4000 values against 4000.pairwise_and/ref_refcensus1881pairwise_and/assign_refcensus1881pairwise_and/lencensus1881and_skewed/and10and_skewed/and_assign10and_skewed/intersection_len10The other seven datasets pooled are 1 to 7% faster for
ref_ref, 0.5 to 3% forassign_refand 11 to 13% forlen. Rows that only take the merge path, such asand_skewed4000, move between -5% and +3%; the same binary against itself reaches 4% on a single row. Same machines and toolchains as #385.Things to look at:
simd, where a 3-run check put the break-even against the vector merge at a ratio of 10 to 20.lower_boundsusesget_unchecked. Checked indexing made the skewed rows 10 to 18% slower in an earlier 3-run check.and_skewedis#[inline(never)]. With#[inline],and_skewed/and4000 was 12% [+8, +17] slower on Zen 3 and 10% [+3, +18] on Zen 5, although the merge loop is the only code that row runs.simd, a skewed&=now builds a new Vec instead of filtering in place.is_disjointandis_subsetstill merge.Tests compare the skewed path with the existing merge on edge cases and a proptest, in both argument orders, for all three operations.
Authored with Claude (claude-opus-5-5).