Optimize small BitMap with long-backed implementation#871
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #871 +/- ##
===========================================
- Coverage 60.51% 60.43% -0.09%
===========================================
Files 741 744 +3
Lines 48722 48963 +241
Branches 7728 7771 +43
===========================================
+ Hits 29486 29589 +103
- Misses 17828 17965 +137
- Partials 1408 1409 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
|
||
| @Override | ||
| void markAll() { | ||
| bits = ALL_BITS_MARKED; |
There was a problem hiding this comment.
size=64: markAll() makes ArrayImpl's 9th padding byte 0xFF, but LongImpl's
getByteArray() keeps it 0 → cross-impl equals/getByteArray mismatch. Please fix
and add a test.
There was a problem hiding this comment.
Thanks for catching this. Fixed by preserving the compatibility padding byte in BitMapLongImpl for size 64 and including it in serialization, reset, clone, equality, hash code, and extension. I also added a regression test comparing markAll() across the array-backed and long-backed implementations.
Summary
BitMapArrayImpland add the sharedBitMapImplabstractionBitMapLongImplfor bitmaps up to 64 bits; public constructors keep the array implementation whilecreateDynamicBitMapselects the implementation by lengthmarkAll,equals,equalsInRange, andhashCodewithout temporary byte arraysTest
BitMapTestTabletTestFloatDecoderTestBitMapPerformanceTestCoverage includes public-constructor and dynamic-factory selection, the 64-to-65-bit expansion path, point and range operations, cross-implementation equality and hash consistency, exhaustive merge offset/length combinations, Tablet serialization/deserialization and append paths, and Float codec bitmap serialization.
Length-64 performance report
Environment
b8825b18, with the BitMap changes appliedMethod
BitMapAPILong/Array < 1meansBitMapLongImplis faster;Long/Array > 1meansBitMapArrayImplis fasterResults
isMarkedisAllMarked/isAllUnmarkedmark/unmarkmarkRange/unmarkRangemarkAll/resetgetByteArraygetTruncatedByteArraybyte[]clonemergeappendgetRegionequals/equalsInRangehashCodetoStringThe optimized
equals/equalsInRangepaths avoid temporary arrays and are 43.6% faster with the long-backed implementation. The long-backedhashCodealso avoids temporary arrays, but its byte-wise calculation remains 34.5% slower than the JVM-optimizedArrays.hashCodepath.Retained memory
RamUsageEstimatorincludes the outerBitMap, its implementation object, and thebyte[]retained by the array implementation, using the current JVM object-header, reference-width, and 8-byte alignment settings.Conclusions and limitations
For bitmaps up to 64 bits that primarily perform marking, lookup, merge, clone, or append operations,
BitMapLongImplreduces retained memory and improves most bit operations. Its main cost is byte-array conversion:getByteArray,getTruncatedByteArray, and construction frombyte[]are slower because a long-backed bitmap must materialize or decode the array representation.This is an in-project JUnit microbenchmark rather than JMH. Warm-up, median aggregation, alternating execution order, and escaping result containers reduce common measurement errors, but absolute ns/op values still depend on CPU frequency, JIT compilation, GC, and background load. Relative ratios should be compared on the same machine and JVM.