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