[Performance] Reduce allocations on aligned tablet writes - #18358
Open
Caideyipi wants to merge 3 commits into
Open
[Performance] Reduce allocations on aligned tablet writes#18358Caideyipi wants to merge 3 commits into
Caideyipi wants to merge 3 commits into
Conversation
Caideyipi
force-pushed
the
perf/aligned-bitmap-range-check
branch
from
July 30, 2026 07:29
90a8f48 to
b2227fd
Compare
Caideyipi
force-pushed
the
perf/aligned-bitmap-range-check
branch
from
July 30, 2026 08:43
b2227fd to
e04c71a
Compare
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
Problem
#18249 made aligned MemTable bitmaps block-lazy, #18276 made primitive value arrays lazy, and #18330 reconciled their actual memory usage. Two allocation hot spots still remained on the aligned tablet write path, especially on Windows:
BitMapLongImpl.getByteArray()was called while checking source-bitmap prefixes. A 64-column batch performed the check twice per column and created about 4 KiB of temporary arrays.nullis necessarily all-null, but the write path nevertheless created and marked a bitmap for that block. Wide sparse writes therefore allocated thousands of bitmap objects for columns that had no value array at all.The second cost is small in a narrow ns-scale microbenchmark, but scales with column count and also adds allocation/GC pressure. It is visible in the 3,000-column Windows case below.
Fix
BitMap.isAllUnmarked(length)for ranges starting at offset 0, inspecting the backing bitmap directly without creating a byte-array copy.Correctness coverage
Manual performance UT
AlignedSparseWritePerformanceTestis disabled by default and reports current-thread CPU time, allocated bytes, peak heap delta, and theoretical avoided bitmap RAM for:Run the default 64-column case with:
mvn -o -nsu -pl iotdb-core/datanode test \ -Dtest=AlignedSparseWritePerformanceTest \ -Diotdb.aligned.sparse-write.perf.enabled=trueThe following properties are independently tunable:
Example wide-table run:
mvn -o -nsu -pl iotdb-core/datanode test \ -Dtest=AlignedSparseWritePerformanceTest \ -Diotdb.aligned.sparse-write.perf.enabled=true \ -Diotdb.aligned.sparse-write.perf.columns=3000 \ -Diotdb.aligned.sparse-write.perf.written-columns=1 \ -Diotdb.aligned.sparse-write.perf.rows=64 \ -Diotdb.aligned.sparse-write.perf.warmup.iterations=20 \ -Diotdb.aligned.sparse-write.perf.iterations=200 \ -Diotdb.aligned.sparse-write.perf.rounds=5Performance
Measured on Windows with Java 17.
Prefix bitmap check
The range-check benchmark used 64 long-backed bitmaps, 102,400,000 checks per round, and the median of 7 rounds.
start=0, length=64)start=1, length=63)Sparse aligned write
For 3,000 columns, one written column, and 64 rows per batch:
Windows current-thread CPU samples are quantized by the platform timer, so the CPU result is directional rather than ns-precise. Thread allocation is stable and shows the main effect directly. The final path avoids 155,948 bytes of bitmap RAM accounting per sparse batch in this setup.
For the default 64-column case, final allocations were:
Extending one column over 65,536 historical rows (1,024 blocks) avoids 53,248 bytes of bitmap RAM accounting per column. The remaining cost is the existing value-list placeholders and schema-array growth, not bitmap objects.
The existing aligned bitmap accounting benchmark also remained non-regressive: dense allocation was unchanged, while the source-bitmap prefix optimization removed about 4 KiB/batch from the measured null-heavy path.
Dense fully aligned single-device follow-up
The implicit-null optimization above targets sparse/all-null writes and therefore does not materially affect the dense, fully aligned ATOMS case. A separate fixed cost remained from #18330: every aligned tablet created a
HashSet, calledsplitByDevice, and retained the set in the RAM-cost snapshot even when the tablet could only contain one device.This follow-up:
singleDeviceby the planner;splitByDevice + HashSetpath for relational multi-device tablets;AlignedBitmapMemoryAccountingPerformanceTestwith a default-off, configurable legacy/current benchmark of the complete snapshot lifecycle (write-before snapshot plus write-after correction). The benchmark forces snapshots to escape so HotSpot cannot hide the production allocations through scalar replacement.Run it with:
mvn -o -nsu -pl iotdb-core/datanode test \ -Dtest=AlignedBitmapMemoryAccountingPerformanceTest \ -Diotdb.aligned.bitmap.accounting.perf.enabled=trueThe existing
columns,rows,warmup.iterations,iterations, androundsproperties remain tunable. With the defaults (64 columns, 256 rows, 2,048,000 snapshot lifecycles per round, median of 5 rounds) on Windows/Java 17:The snapshot sub-path is about 40% faster and allocates 87.9% less, but dense tablet writing itself measured 23-31 us/tablet on Windows. The net saving is only about 0.10-0.13% of dense-write CPU and 0.29% of dense-write allocation. This is a low-risk cleanup, not an explanation for the large ATOMS regression.
Verification
mvn -o -nsu spotless:apply -pl iotdb-core/datanodemvn -o -nsu -pl iotdb-core/datanode test-compile -DskipTestsAlignedTVListTest: 19 passedAlignedTVListIteratorTest: 12 passedTsFileProcessorTestmethods: 6 passedAlignedSparseWritePerformanceTest: passed when enabled for both 64-column and 3,000-column configurationsAlignedBitmapMemoryAccountingPerformanceTest: passed when enabled with the configurable dense single-device legacy/current benchmarkgit diff --check: passedThis PR has:
Key changed/added classes
AlignedTVList: allocation-free prefix checks and deferred bitmap allocation for implicit-null blocks.AlignedTVListTest: correctness and memory-accounting coverage.TsFileProcessorandRelationalInsertTabletNode: direct-device RAM snapshot path for known single-device tablets.TsFileProcessorTest: aligned MemTable RAM expectations and single-/multi-device snapshot dispatch coverage.AlignedBitmapRangeCheckPerformanceTest: opt-in legacy/current prefix range benchmark.AlignedSparseWritePerformanceTest: configurable sparse-write CPU/allocation benchmark.AlignedBitmapMemoryAccountingPerformanceTest: configurable dense single-device snapshot CPU/allocation benchmark.