RFR: 8316426: Optimization for HexFormat.formatHex
温绍锦
duke at openjdk.org
Mon Sep 18 15:45:02 UTC 2023
On Fri, 15 Sep 2023 18:20:32 GMT, Claes Redestad <redestad at openjdk.org> wrote:
> What numbers do you get with this?
>
> In my experiments the improvement was either negligible or small enough to hardly matter. I also tried flipping bits similar to what you're doing for uppercasing but saw a net regression from that.
>
> I opted for simplicity in #15991 - a simple cleanup that removed a few tiny lookup-tables and still led to a decent improvement. Going the other direction seems like the wrong move.
The byte[] length used by HexFormatBench is 512. In this scenario, the performance improvement of using table lookup is significant.
> I don't think `appendHex` would make the cut as a public API. I think we would need something with much more general utility for that.
>
> A more high-level idea would be to improve said `String` templates JEP to be able to format more generally into `Appendable`/`StringBuilder`, so that hex, octal - any custom format - can be efficiently appended to a `StringBuilder`.
>
> BTW, here's a patch on top of #15768 that simplifies `formatHex(Appendable..)` to simply append the result of `formatHex(byte[]...)`:
>
>
> Benchmark (size) Mode Cnt Score Error Units
> HexFormatBench.appenderLowerCached 512 avgt 15 0,202 ± 0,001 us/op
> HexFormatBench.formatLowerCached 512 avgt 15 0,189 ± 0,016 us/op
>
>
> Same speed. Drawback is that the `appender` becomes allocating but short-lived allocations is one of my least concerns:
>
> ```java
> diff --git a/src/java.base/share/classes/java/util/HexFormat.java b/src/java.base/share/classes/java/util/HexFormat.java
> index e1d88e3ceb6..68a15307fe0 100644
> --- a/src/java.base/share/classes/java/util/HexFormat.java
> +++ b/src/java.base/share/classes/java/util/HexFormat.java
> @@ -407,38 +407,7 @@ public <A extends Appendable> A formatHex(A out, byte[] bytes, int fromIndex, in
> int length = toIndex - fromIndex;
> if (length > 0) {
> try {
> - boolean prefixEmpty = prefix.isEmpty();
> - boolean suffixEmpty = suffix.isEmpty();
> - boolean delimiterEmpty = delimiter.isEmpty();
> - if (!prefixEmpty) {
> - out.append(prefix);
> - }
> - if (suffixEmpty && delimiterEmpty && prefixEmpty) {
> - if (out instanceof StringBuilder sb) {
> - jla.appendHex(sb, digitCase == Case.UPPERCASE, bytes, fromIndex, toIndex);
> - } else {
> - for (int i = 0; i < length; i++) {
> - toHexDigits(out, bytes[fromIndex + i]);
> - }
> - }
> - } else {
> - toHexDigits(out, bytes[fromIndex]);
> - for (int i = 1; i < length; i++) {
> - if (!suffixEmpty) {
> - out.append(suffix);
> - }
> - if (!delimiterEmpty) {
> - out.append(delimiter);
> - ...
@cl4es Can you help me create an issue for this PR?
-------------
PR Comment: https://git.openjdk.org/jdk/pull/15768#issuecomment-1721726615
PR Comment: https://git.openjdk.org/jdk/pull/15768#issuecomment-1722356329
More information about the core-libs-dev
mailing list