RFR: 8315789: Minor HexFormat performance improvements

Claes Redestad redestad at openjdk.org
Wed Sep 6 19:26:39 UTC 2023


On Wed, 6 Sep 2023 16:10:23 GMT, Claes Redestad <redestad at openjdk.org> wrote:

>> src/java.base/share/classes/java/util/HexFormat.java line 644:
>> 
>>> 642:             return (char)('a' - 10 + value);
>>> 643:         }
>>> 644:         return (char)('A' - 10 + value);
>> 
>> Not sure if this would adversely impact performance, but what about factoring out these lines in a private method? They are repeated in `toHighHexDigit`.
>
> Surprisingly this does carry some cost in the microbenchmarks on my M1. Might be noise, but it seems rather consistent so I'll need to investigate.

This:

diff --git a/src/java.base/share/classes/java/util/HexFormat.java b/src/java.base/share/classes/java/util/HexFormat.java
index 107c362cbc2..177548c03f7 100644
--- a/src/java.base/share/classes/java/util/HexFormat.java
+++ b/src/java.base/share/classes/java/util/HexFormat.java
@@ -634,14 +634,7 @@ private static String escapeNL(String string) {
      * @return the hexadecimal character for the low 4 bits {@code 0-3} of the value
      */
     public char toLowHexDigit(int value) {
-        value = value & 0xf;
-        if (value < 10) {
-            return (char)('0' + value);
-        }
-        if (digitCase == Case.LOWERCASE) {
-            return (char)('a' - 10 + value);
-        }
-        return (char)('A' - 10 + value);
+        return toHexDigit(value & 0xf);
     }

     /**
@@ -655,7 +648,10 @@ public char toLowHexDigit(int value) {
      * @return the hexadecimal character for the bits {@code 4-7} of the value
      */
     public char toHighHexDigit(int value) {
-        value = (value >> 4) & 0xf;
+        return toHexDigit((value >> 4) & 0xf);
+    }
+
+    private char toHexDigit(int value) {
         if (value < 10) {
             return (char)('0' + value);
         }

.. clearly increase cost across all micros:


Name                               Cnt  Base   Error   Test   Error  Unit   Diff%
HexFormatBench.appenderLower        15 1,046 ± 0,041  1,301 ± 0,017 us/op  -24,4% (p = 0,000*)
HexFormatBench.appenderLowerCached  15 1,056 ± 0,055  1,175 ± 0,115 us/op  -11,3% (p = 0,001*)
HexFormatBench.appenderUpper        15 1,059 ± 0,055  1,303 ± 0,012 us/op  -23,0% (p = 0,000*)
HexFormatBench.appenderUpperCached  15 1,099 ± 0,014  1,451 ± 0,267 us/op  -32,0% (p = 0,000*)
HexFormatBench.toHexLower           15 0,322 ± 0,002  0,338 ± 0,005 us/op   -4,8% (p = 0,000*)
HexFormatBench.toHexLowerCached     15 0,324 ± 0,003  0,411 ± 0,005 us/op  -27,0% (p = 0,000*)
HexFormatBench.toHexUpper           15 0,324 ± 0,003  0,340 ± 0,003 us/op   -4,9% (p = 0,000*)
HexFormatBench.toHexUpperCached     15 0,322 ± 0,001  0,411 ± 0,004 us/op  -27,6% (p = 0,000*)

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/15591#discussion_r1317728161


More information about the core-libs-dev mailing list