Repository navigation
Avoid sorting large BatchEqual queries on small indexes - #588
Open
perfloop-agent wants to merge 5 commits into
Open
perfloop-agent wants to merge 5 commits into
perfloop-agent wants to merge 5 commits into
Conversation
Signed-off-by: Perfloop Agent <agent@perfloop.ai> Signed-off-by: Tomás Senart <ts@perfloop.ai>
Signed-off-by: Perfloop Agent <agent@perfloop.ai> Signed-off-by: Tomás Senart <ts@perfloop.ai>
Signed-off-by: Perfloop Agent <agent@perfloop.ai> Signed-off-by: Tomás Senart <ts@perfloop.ai>
Signed-off-by: Perfloop Agent <agent@perfloop.ai> Signed-off-by: Tomás Senart <ts@perfloop.ai>
Signed-off-by: Perfloop Agent <agent@perfloop.ai> Signed-off-by: Tomás Senart <ts@perfloop.ai>
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.
Description
Avoid sorting large
BatchEqualquery lists when the index is small. In #532 (dac837d3bbc8, contributed byperfloop-agent), we added sorting of every retained nonempty query before dispatch. That regressed large IN-lists on small indexes, which payO(m log m)sorting even when there is only one stored column.Type of Change
Changes Made
What was changed?
Why was it changed?
How was it changed?
BenchmarkBatchEqualShuffledin BitSliceIndexing/bsi_benchmark_test.go.TestBatchEqualSmallIndexandTestBatchEqualSmallIndexOrderingcheck results on the new paths. Both also pass at base, so they are not regression tests for the slowdown.Testing
Go tests passed for the root, BitSliceIndexing, and roaring64 packages; BitSliceIndexing's race-enabled tests also passed.
TestBatchEqualSmallIndexandTestBatchEqualSmallIndexOrderingcheck GetValue equivalence, hits and misses, signed and narrow values, duplicates, unrepresentable values, existence/plane divergence, result isolation, parallelism, run optimization, shuffled contiguous sets with a nonzero minimum, ordered queries, and non-contiguous sets whose first values span the full range.Formatting
gofmtandgo vetpassed for the BitSliceIndexing package.Fuzzing
Not run. The template's FuzzSmat target is not defined in the repository, and smat exercises the root roaring package, not BitSliceIndexing.
Performance Impact
Local run: Go 1.24.4,
GOMAXPROCS=4, preloaded 64-plane indexes and deterministically shuffled distinct query values. The one-column queries contain their stored value; the control query matches 100 of 100000 columns. Setup and shuffling are outside the measured completeBatchEqual(0, values)calls.Pre-#532 is its parent
bd4128b. Base is33586cewith the benchmark; to reproduce it, use this PR's head with thebsi.gochange reverted. Fix is this change. All three arms use the same benchmark file. Three measured triples per shape, with randomized arm order, one excluded warmup triple, and one second per invocation.The table shows separate arm medians and median paired change (fix minus base); percentages use the base median. The 100000-column/100-value rows are a regression control, not a speedup claim.
Exact local Go output from the first measured triple
Pre-#532 — first measured triple:
Base — first measured triple:
Fix — first measured triple:
Running Benchmarks
Build each revision's benchmark once, then alternate the revisions for each group. Run each columns/values combination in the table with the corresponding exact selection, for example:
For the pre-#532 run, copy this PR's
BitSliceIndexing/bsi_benchmark_test.goand thesetupRunOptimizedQueryBSIhelper fromBitSliceIndexing/bsi_test.gointo that tree; the helper is needed to compile unrelated benchmarks, not called by these measurements.Performance Analysis
The small-index scan avoids sorting and the trie's per-branch bitmaps (allocations fall from about 36,000 to 334 at 781 and 782 columns), including both sides of the former 781/782-column boundary and the 12799-value case. Deduplication, the query slice, worker buffers, and bitmap construction remain costs; these results do not establish parity with pre-#532.
The one-column/1000-value case uses more allocations than base. The large-index/small-query control's elapsed estimate is lower in this run, while allocated bytes and allocation count are slightly higher; it is not an improvement claim.
These results cover generated shuffled inputs, not a production query distribution. Indexes with fewer than four query values per column still sort, then use the trie or, at 100,000 or more columns, the scan fallback.
Breaking Changes
None. Public signatures and result semantics are unchanged.
Related Issues
Related to #532 and #533.
Additional Notes
No changes to query filtering or existence-bitmap authority. The comparison uses
33586ce, not the original report's0cca44e; theBatchEqualimplementation is identical at those two upstream revisions.Case and evidence
Made by Perfloop. Human sponsor: Tomás Senart. To ask for a change, comment or review in plain words. How Perfloop handles pull requests.