perf(util): add FixedBitSet.copyOf() fast paths for SparseLiveDocs and DenseLiveDocs#16282
Open
salvatorecampagna wants to merge 3 commits into
Open
Conversation
FixedBitSet.copyOf(Bits) already has fast paths for FixedBitSet and FixedBits, but SparseLiveDocs and DenseLiveDocs (introduced in apache#15413) fell through to the O(maxDoc) generic loop. Each type now exposes a package-private toFixedBitSet() method that FixedBitSet.copyOf() delegates to: - DenseLiveDocs stores live docs in a FixedBitSet: clone it directly, O(maxDoc/64). - SparseLiveDocs stores deleted docs in a SparseFixedBitSet: pre-fill the backing long[] with -1L and clear only deleted positions using nextSetBit, O(deletedDocs + maxDoc/64). The hot caller is PendingDeletes.getMutableBits(), which invokes copyOf(liveDocs) on the first delete after a snapshot.
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.
TL;DR
Make
FixedBitSet.copyOf()135x to 193x faster forDenseLiveDocsand 11x to 48x faster forSparseLiveDocs.Summary
FixedBitSet.copyOf(Bits)has fast paths forFixedBitSetandFixedBitsbut not forSparseLiveDocsandDenseLiveDocs, the twoLiveDocstypes introduced in #15413. Both fall through to the generic O(maxDoc) per-bit loop. The hot caller isPendingDeletes.getMutableBits(), which invokesFixedBitSet.copyOf(liveDocs)on the first delete after a reader snapshot. Under write-heavy workloads this cost accumulates across open reader generations.Each type now exposes a package-private
toFixedBitSet()method thatFixedBitSet.copyOf()delegates to, keeping the copy logic next to the data it knows about.DenseLiveDocsstores live docs in aFixedBitSetwith identical semantics, sotoFixedBitSet()clones it at O(maxDoc/64).SparseLiveDocsstores deleted positions in aSparseFixedBitSet, sotoFixedBitSet()allocates the backinglong[]prefilled with-1L(all live), masks off the ghost bits in the last word to satisfyFixedBitSetinvariants, then clears only the deleted positions vianextSetBitat O(maxDoc/64 + deletedDocs).Benchmarks
LiveDocsCopyOfBenchmark,FixedBitSet.copyOf()average time (us/op),-wi 5 -i 7 -f 3. Baseline =mainHEAD; contender = this PR.DenseLiveDocs
SparseLiveDocs
The
SparseLiveDocsspeedup shrinks as the deletion rate grows: the contender always pays O(maxDoc/64) to fill the backing array, and on top of that clears one position per deleted document. At low deletion rates the fill dominates and the gap with the O(maxDoc) baseline is large; at higher rates the clearing loop contributes more and the advantage narrows.