perf: optimize bitmapContainer.fillLeastSignificant16bits using TrailingZeros64#534
Open
perfloop-agent wants to merge 1 commit into
Open
perf: optimize bitmapContainer.fillLeastSignificant16bits using TrailingZeros64#534perfloop-agent wants to merge 1 commit into
perfloop-agent wants to merge 1 commit into
Conversation
…ingZeros64 Signed-off-by: Perfloop Agent <agent@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
This PR optimizes the dense bitmap array materialization loop in
bitmapContainer.fillLeastSignificant16bitsusingmath/bits.TrailingZeros64and clear-lowest-bit stepbitset &= bitset - 1.On amd64 architectures, this loop compiles down to efficient TZCNT/BLSR instructions. By using these instructions, we reduce the scalar instructions required per set bit and significantly optimize dense bitmap array materialization.
A comprehensive differential property test
TestBitmapContainerFillLeastSignificant16bitsPropertiesis also added to thoroughly verify 16-bit range correctness, boundary conditions, and return values.Type of Change
Changes Made
What was changed?
The scalar loop decoding each set bit in
bitmapContainer.fillLeastSignificant16bitswas rewritten. Instead of using the legacy isolate-lowest-bitt := bitset & -bitsetandpopcount(t-1)operations, the code now extracts the trailing zeros withmath/bits.TrailingZeros64and clears the lowest set bit usingbitset &= bitset - 1. Additionally, the comment above this loop has been updated to scope any named instruction lowering specifically to the amd64 ISA.Why was it changed?
The previous implementation performed extra arithmetic work (including popcount and bitwise XOR) for every single set bit during dense bitmap materialization. By leveraging standard compiler intrinsic patterns, the decoding overhead is reduced.
How was it changed?
The implementation in
bitmapcontainer.gowas updated. A comprehensive property-based testTestBitmapContainerFillLeastSignificant16bitsPropertieswas added tobitmapcontainer_test.goand a new benchmarkBenchmarkBitmapContainerFillLeastSignificant16bitswas added tobitmapcontainer_bench_test.go.Testing
Standard repository-level correctness tests run and pass. The test suite covering
fillLeastSignificant16bitscorrectness (Verify fillLeastSignificant16bits correctness, which executes theTestRle16RandomFillLeastSignificant16bits029test) runs successfully, as does the newly added differential property testTestBitmapContainerFillLeastSignificant16bitsProperties.Formatting
The code adheres strictly to repository code style guidelines:
gofmtcode formatting check.go tool unconvert.Fuzzing
Input validation and boundary coverage are verified through extensive property-based test sweeps. The property-based tests cover random dense and sparse regimes over the full 16-bit container bounds.
Performance Impact
Co-measured benchmark runs on the tested amd64 architecture show a significant improvement in execution time with no changes in memory allocations or object counts. The benchmark was authored by the agent to measure this specific container materialization hot path.
Before:
BenchmarkBitmapContainerFillLeastSignificant16bits-4 1000000 41864.5 ns/op 0 B/op 0 allocs/op
After:
BenchmarkBitmapContainerFillLeastSignificant16bits-4 1000000 29265 ns/op 0 B/op 0 allocs/op
ns/op:41864.5 -> 29265(effect30.0959%improvement,p=1.08251e-05, significant, candidaten=10) [PRIMARY WIN outcome=won]B/op:0 -> 0(effect0%,p=1, not significant, candidaten=10) [GUARDRAIL outcome=held]allocs/op:0 -> 0(effect0%,p=1, not significant, candidaten=10) [GUARDRAIL outcome=held]Reproduction
To reproduce these measurements, run the following benchmark command in the repository root:
Testing Environment
dac837d3bbc8b5113e8a313372139bf0cf4f7a2327eb31dc3f7baadf776f5e94b6888a278ec3a21dBreaking Changes
There are no breaking changes. This change is entirely backwards-compatible and introduces no behavior or API modifications.
Alternatives and Prior Candidates Tried
The following alternative candidates were developed and evaluated during the refinement process for this case:
cand_at53nxpm5g(commit45732f8bc1ccbd1f3658766a311345d9149023a0): Replaced the legacy isolate-lowest-bit plus popcount(t-1) decode loop inbitmapContainer.fillLeastSignificant16bitswithmath/bits.TrailingZeros64(bitset)andbitset &= bitset - 1but did not include the comprehensive property-based tests.cand_3y82vyccvm(commit8936137470283be1f3600a661232add5c3c801fb): Added the property test and benchmark, but retained an obsolete assembly comment.cand_d2z8fp1zze(commit2e80009f045a1bc4f80ceb4cf2fe8de9101818ae): Optimized the dense bitmap array materialization and updated comments, but the comments made a universal (architecture-independent) claim about the lowering to TZCNT/BLSR. The current candidatecand_6ad8gs5srwaddresses feedback by scoping that comment specifically to theamd64architecture.Full proof of optimization and verified measurements can be found on the canonical case page: https://app.perfloop.ai/t/oss/case_74j4gzmye2
This is an automated, human-reviewed Perfloop contribution opened by perfloop-agent. The body links to reproducible proof for the change. The change was benchmarked on perfloop/roaring, an automation fork of RoaringBitmap/roaring; the commit on this PR's head branch carries the proof.
Assisted-by: PerfloopAgent:gemini-3.5-flash