RFR: 8347167: Reduce allocation in com.sun.net.httpserver.Headers::normalize [v3]
Volkan Yazici
vyazici at openjdk.org
Thu Nov 20 10:29:32 UTC 2025
On Wed, 19 Nov 2025 14:09:09 GMT, Josiah Noel <duke at openjdk.org> wrote:
>> Following the direction outlined in the net-dev discussion, I've updated the `com.sun.net.httpserver.Headers.normalize()` method to no longer allocate a superfluous char array when the header is already normalized.
>
> Josiah Noel has updated the pull request incrementally with one additional commit since the last revision:
>
> patch 2
Performance figures using 1a849f44c01:
Benchmark (key) Mode Cnt Score Error Units
HeaderNormalization.n25 Accept-charset avgt 15 12.384 ± 0.238 ns/op
HeaderNormalization.n25 4ccept-charset avgt 15 12.345 ± 0.204 ns/op
HeaderNormalization.n25 accept-charset avgt 15 12.749 ± 0.386 ns/op
HeaderNormalization.n25 Accept-Charset avgt 15 12.472 ± 0.252 ns/op
HeaderNormalization.n25 ACCEPT-CHARSET avgt 15 12.923 ± 0.200 ns/op
HeaderNormalization.n26 Accept-charset avgt 15 8.087 ± 0.067 ns/op
HeaderNormalization.n26 4ccept-charset avgt 15 8.085 ± 0.054 ns/op
HeaderNormalization.n26 accept-charset avgt 15 12.488 ± 0.224 ns/op
HeaderNormalization.n26 Accept-Charset avgt 15 15.818 ± 0.667 ns/op
HeaderNormalization.n26 ACCEPT-CHARSET avgt 15 13.693 ± 0.159 ns/op
with GC statistics:
Benchmark (key) Mode Cnt Score Error Units
HeaderNormalization.n25 Accept-charset avgt 15 12.384 ± 0.238 ns/op
HeaderNormalization.n25:gc.alloc.rate Accept-charset avgt 15 8009.345 ± 153.162 MB/sec
HeaderNormalization.n25:gc.alloc.rate.norm Accept-charset avgt 15 104.000 ± 0.001 B/op
HeaderNormalization.n25:gc.count Accept-charset avgt 15 129.000 counts
HeaderNormalization.n25:gc.time Accept-charset avgt 15 84.000 ms
HeaderNormalization.n25 4ccept-charset avgt 15 12.345 ± 0.204 ns/op
HeaderNormalization.n25:gc.alloc.rate 4ccept-charset avgt 15 8033.964 ± 130.861 MB/sec
HeaderNormalization.n25:gc.alloc.rate.norm 4ccept-charset avgt 15 104.000 ± 0.001 B/op
HeaderNormalization.n25:gc.count 4ccept-charset avgt 15 84.000 counts
HeaderNormalization.n25:gc.time 4ccept-charset avgt 15 61.000 ms
HeaderNormalization.n25 accept-charset avgt 15 12.749 ± 0.386 ns/op
HeaderNormalization.n25:gc.alloc.rate accept-charset avgt 15 7783.679 ± 232.103 MB/sec
HeaderNormalization.n25:gc.alloc.rate.norm accept-charset avgt 15 104.000 ± 0.001 B/op
HeaderNormalization.n25:gc.count accept-charset avgt 15 84.000 counts
HeaderNormalization.n25:gc.time accept-charset avgt 15 61.000 ms
HeaderNormalization.n25 Accept-Charset avgt 15 12.472 ± 0.252 ns/op
HeaderNormalization.n25:gc.alloc.rate Accept-Charset avgt 15 7953.160 ± 160.314 MB/sec
HeaderNormalization.n25:gc.alloc.rate.norm Accept-Charset avgt 15 104.000 ± 0.001 B/op
HeaderNormalization.n25:gc.count Accept-Charset avgt 15 132.000 counts
HeaderNormalization.n25:gc.time Accept-Charset avgt 15 84.000 ms
HeaderNormalization.n25 ACCEPT-CHARSET avgt 15 12.923 ± 0.200 ns/op
HeaderNormalization.n25:gc.alloc.rate ACCEPT-CHARSET avgt 15 7674.346 ± 117.355 MB/sec
HeaderNormalization.n25:gc.alloc.rate.norm ACCEPT-CHARSET avgt 15 104.000 ± 0.001 B/op
HeaderNormalization.n25:gc.count ACCEPT-CHARSET avgt 15 151.000 counts
HeaderNormalization.n25:gc.time ACCEPT-CHARSET avgt 15 93.000 ms
HeaderNormalization.n26 Accept-charset avgt 15 8.087 ± 0.067 ns/op
HeaderNormalization.n26:gc.alloc.rate Accept-charset avgt 15 0.007 ± 0.001 MB/sec
HeaderNormalization.n26:gc.alloc.rate.norm Accept-charset avgt 15 ≈ 10⁻⁴ B/op
HeaderNormalization.n26:gc.count Accept-charset avgt 15 ≈ 0 counts
HeaderNormalization.n26 4ccept-charset avgt 15 8.085 ± 0.054 ns/op
HeaderNormalization.n26:gc.alloc.rate 4ccept-charset avgt 15 0.007 ± 0.001 MB/sec
HeaderNormalization.n26:gc.alloc.rate.norm 4ccept-charset avgt 15 ≈ 10⁻⁴ B/op
HeaderNormalization.n26:gc.count 4ccept-charset avgt 15 ≈ 0 counts
HeaderNormalization.n26 accept-charset avgt 15 12.488 ± 0.224 ns/op
HeaderNormalization.n26:gc.alloc.rate accept-charset avgt 15 7942.420 ± 142.330 MB/sec
HeaderNormalization.n26:gc.alloc.rate.norm accept-charset avgt 15 104.000 ± 0.001 B/op
HeaderNormalization.n26:gc.count accept-charset avgt 15 134.000 counts
HeaderNormalization.n26:gc.time accept-charset avgt 15 84.000 ms
HeaderNormalization.n26 Accept-Charset avgt 15 15.818 ± 0.667 ns/op
HeaderNormalization.n26:gc.alloc.rate Accept-Charset avgt 15 6278.022 ± 272.604 MB/sec
HeaderNormalization.n26:gc.alloc.rate.norm Accept-Charset avgt 15 104.000 ± 0.001 B/op
HeaderNormalization.n26:gc.count Accept-Charset avgt 15 188.000 counts
HeaderNormalization.n26:gc.time Accept-Charset avgt 15 115.000 ms
HeaderNormalization.n26 ACCEPT-CHARSET avgt 15 13.693 ± 0.159 ns/op
HeaderNormalization.n26:gc.alloc.rate ACCEPT-CHARSET avgt 15 7242.221 ± 84.263 MB/sec
HeaderNormalization.n26:gc.alloc.rate.norm ACCEPT-CHARSET avgt 15 104.000 ± 0.001 B/op
HeaderNormalization.n26:gc.count ACCEPT-CHARSET avgt 15 211.000 counts
HeaderNormalization.n26:gc.time ACCEPT-CHARSET avgt 15 126.000 ms
Let me highlight certain details:
### If the input is already normalized
:green_circle: Performance has increased 34%:
Benchmark (key) Mode Cnt Score Error Units
HeaderNormalization.n25 Accept-charset avgt 15 12.384 ± 0.238 ns/op
HeaderNormalization.n25 4ccept-charset avgt 15 12.345 ± 0.204 ns/op
HeaderNormalization.n26 Accept-charset avgt 15 8.087 ± 0.067 ns/op
HeaderNormalization.n26 4ccept-charset avgt 15 8.085 ± 0.054 ns/op
100 * (1 - (avg(8.087, 8.085) / avg(12.384, 12.345)))
# ≈ 34
The new `normalize()` incurs no GC – see `gc.count ... ≈ 0` lines.
### If the input is *not* normalized
🔴 Performance has dropped 10%:
Associated GC costs are not impacted – see matching `gc.alloc.rate.norm` figures between `n25` and `n26`.
Benchmark (key) Mode Cnt Score Error Units
HeaderNormalization.n25 accept-charset avgt 15 12.749 ± 0.386 ns/op
HeaderNormalization.n25 Accept-Charset avgt 15 12.472 ± 0.252 ns/op
HeaderNormalization.n25 ACCEPT-CHARSET avgt 15 12.923 ± 0.200 ns/op
HeaderNormalization.n26 accept-charset avgt 15 12.488 ± 0.224 ns/op
HeaderNormalization.n26 Accept-Charset avgt 15 15.818 ± 0.667 ns/op
HeaderNormalization.n26 ACCEPT-CHARSET avgt 15 13.693 ± 0.159 ns/op
100 * (1 - (avg(12.488, 15.818, 13.693) / avg(12.749, 12.472, 12.923)))
# ≈ -10.106438758389258
-------------
PR Comment: https://git.openjdk.org/jdk/pull/27276#issuecomment-3557119364
More information about the net-dev
mailing list