Eliminate AsciiString's resize-copy after exact allocation
perfloop/netty · AVOIDABLE COPY
https://perfloop.ai/t/oss/case_dyqr11pchm
Verdict
VERIFIED · settled 2026-08-04
What happened: The paired measurements met the required improvement.
Hypothesis
I ran a source-level value-flow check, not a runtime profile: `ByteBufUtil` lines 829-832 allocate `utf8MaxBytes(seq)`; lines 1154-1158 make that exactly n for `AsciiString`; but lines 844-846 recompute the reservation from the integer length as 3n. The traced write path calls `ensureWritable0` before encoding, while the `AsciiString` encoder writes only n bytes (lines 882-892 and 911-914). `AbstractByteBuf.ensureWritable0` grows when capacity is below the requested reservation (lines 284-305). For the standard unpooled heap implementation, `UnpooledHeapByteBuf.capacity` allocates a new array and `System.arraycopy`s the entire old capacity on growth (lines 118-137), so an empty newly allocated n-byte buffer can copy n bytes solely because the later reservation is 3n. This establishes the conditional mechanism, but not its production frequency, allocator mix, or CPU share. Reproduce with a focused benchmark using non-empty `AsciiString` values across 1 KiB to 64 KiB and an unpooled heap allocator plus the deployed allocator: compare current code with the carried-reserve variant, and require allocator/JFR allocation evidence that the baseline enters capacity growth and copies n bytes while the variant does not, then measure allocation bytes/op and encoding latency at the observed call cadence.
Change to test: Carry the initial `utf8MaxBytes(seq)` result into `reserveAndWriteUtf8` instead of calling the overload that recomputes a 3x reservation; retain the existing 3x reserve for non-`AsciiString` inputs and verify returned-buffer compatibility.
Where it lives
perfloop/netty · buffer/src/main/java/io/netty/buffer/ByteBufUtil.java
Evidence
AsciiString UTF-8 write plus three equal appends, unpooled heap, 1 KiB · 10 sample pairs
| metric | baseline | candidate | paired median change | confidence range | required | result |
|---|---|---|---|---|---|---|
ns/op |
749.8 |
563.9 |
−24.4% (−183) |
−199.1 to −109 |
< 0 |
PASSED |
B/op |
5216 |
4176 |
−19.9% (−1040) |
−1040 to −1040 |
< 0 |
PASSED |
AsciiString UTF-8 write plus three equal appends, unpooled heap, 4 KiB · 10 sample pairs
| metric | baseline | candidate | paired median change | confidence range | required | result |
|---|---|---|---|---|---|---|
B/op |
20576 |
16464 |
−20% (−4112) |
−4112 to −4112 |
< 0 |
PASSED |
AsciiString UTF-8 write plus three equal appends, unpooled heap, 16 KiB · 10 sample pairs
| metric | baseline | candidate | paired median change | confidence range | required | result |
|---|---|---|---|---|---|---|
B/op |
82016 |
65616 |
−20% (−16400) |
−16400 to −16400 |
< 0 |
PASSED |
AsciiString UTF-8 write plus three equal appends, unpooled heap, 64 KiB · 10 sample pairs
| metric | baseline | candidate | paired median change | confidence range | required | result |
|---|---|---|---|---|---|---|
ns/op |
65776 |
51562 |
−21.4% (−14054) |
−16260 to −12667 |
< 0 |
PASSED |
B/op |
327776 |
262224 |
−20% (−65552) |
−65552 to −65552 |
< 0 |
PASSED |
AsciiString UTF-8 write, default adaptive allocator, 1 KiB · 10 sample pairs
| metric | baseline | candidate | paired median change | confidence range | required | result |
|---|---|---|---|---|---|---|
ns/op |
178.8 |
106.7 |
−39.6% (−70.76) |
−78.84 to −65.2 |
< 0 |
PASSED |
AsciiString UTF-8 write, default adaptive allocator, 4 KiB · 10 sample pairs
| metric | baseline | candidate | paired median change | confidence range | required | result |
|---|---|---|---|---|---|---|
ns/op |
294.4 |
181.5 |
−36.4% (−107.1) |
−130.8 to −98.67 |
< 0 |
PASSED |
AsciiString UTF-8 write, default adaptive allocator, 16 KiB · 10 sample pairs
| metric | baseline | candidate | paired median change | confidence range | required | result |
|---|---|---|---|---|---|---|
ns/op |
1018 |
517.5 |
−49.7% (−505.7) |
−554.7 to −484.8 |
< 0 |
PASSED |
AsciiString UTF-8 write, default adaptive allocator, 64 KiB · 10 sample pairs
| metric | baseline | candidate | paired median change | confidence range | required | result |
|---|---|---|---|---|---|---|
ns/op |
3531 |
1853 |
−49% (−1730) |
−1912 to −1565 |
< 0 |
PASSED |
Checks: 1 of 1 passed. Verification: no defect found.