Skip to content

[improve][broker] Optimize SegmentedLongArray with heap-backed long[][]#26183

Open
nodece wants to merge 1 commit into
apache:masterfrom
nodece:optimize-SegmentedLongArray-with-long
Open

[improve][broker] Optimize SegmentedLongArray with heap-backed long[][]#26183
nodece wants to merge 1 commit into
apache:masterfrom
nodece:optimize-SegmentedLongArray-with-long

Conversation

@nodece

@nodece nodece commented Jul 13, 2026

Copy link
Copy Markdown
Member

Motivation

SegmentedLongArray previously used Netty ByteBuf as its backing store. Every readLong/writeLong operation went through ByteBuf.getLong()/setLong(), adding extra indirection on the hot path of TripleLongPriorityQueue heap operations(siftUp/siftDown).

PR #26010 identified SegmentedLongArray as the remaining bottleneck after optimizing the heap algorithms, and suggested replacing the backing storage with primitive arrays.

This PR replaces the ByteBuf backing store with segmented heap-backed long[][] arrays while preserving the segmented architecture required to support capacities beyond Integer.MAX_VALUE elements (PR #16490).

Modifications

  • SegmentedLongArray
    • Replace the ByteBuf backing store with segmented heap-backed long[][] arrays.
    • Use bit-shift/bit-mask for segment lookup instead of division/modulo.
    • Grow the outer segment array using an amortized expansion strategy to avoid copying on every new segment allocation.

Benchmark Results

JMH benchmarks from TripleLongPriorityQueueBenchmark(2 forks, 3 warmup iterations, 5 measurement iterations, JDK 21.0.5).

Before (ByteBuf)

Benchmark Size Score (us/op) Error
recoveryBulkAddThenPop 500,000 454,423 ±142,390
recoveryBulkAddThenPop 2,000,000 2,406,656 ±680,108
interleavedAddPop 500,000 335,764 ±461,320
interleavedAddPop 2,000,000 1,560,565 ±403,289
steadyState 500,000 261,449 ±11,931
steadyState 2,000,000 1,148,007 ±699,420

After (heap-backed long[][])

Benchmark Size Score (us/op) Error
recoveryBulkAddThenPop 500,000 337,634 ±6,460
recoveryBulkAddThenPop 2,000,000 1,805,059 ±99,786
interleavedAddPop 500,000 231,696 ±1,425
interleavedAddPop 2,000,000 1,102,539 ±89,740
steadyState 500,000 261,390 ±7,856
steadyState 2,000,000 1,054,573 ±58,502

Comparison (Size = 2,000,000)

Benchmark Before (ms) After (ms) Improvement
recoveryBulkAddThenPop 2,407 1,805 +25%
interleavedAddPop 1,561 1,103 +29%
steadyState 1,148 1,055 +8%

Note: The baseline measurements showed relatively large variance in some
scenarios, while the new implementation produced noticeably more stable
results. The reported improvements should therefore be interpreted together
with the benchmark error margins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant