JDK-8042990 : Optimize conversion to hex string
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P5
  • Status: Closed
  • Resolution: Won't Fix
  • Submitted: 2014-05-13
  • Updated: 2017-05-19
  • Resolved: 2014-10-01
Related Reports
Relates :  
Relates :  
Description
jdk/src/share/classes/sun/security/smartcardio/PCSC.java

    private final static char[] hexDigits = "0123456789abcdef".toCharArray();

    public static String toString(byte[] b) {
        StringBuffer sb = new StringBuffer(b.length * 3);
        for (int i = 0; i < b.length; i++) {
            int k = b[i] & 0xff;
            if (i != 0) {
                sb.append(':');
            }
            sb.append(hexDigits[k >>> 4]);
            sb.append(hexDigits[k & 0xf]);
        }
        return sb.toString();
    }


Can be replaced with

            sb.append(Integer.toHexString(k >>> 4));
            sb.append(Integer.toHexString(k & 0xf));


Comments
The fastest version appears to be the following one: static String toString(byte[] b) { if (b == null) { return "(null)"; } if (b.length == 0) { return ""; } char buf[] = new char[b.length * 3 - 1]; int k = b[0] & 0xff; buf[0] = hexDigits[k >>> 4]; buf[1] = hexDigits[k & 0xf]; for (int i = 1; i < b.length; ) { k = b[i] & 0xff; buf[i++] = ':'; buf[i++] = hexDigits[k >>> 4]; buf[i++] = hexDigits[k & 0xf]; } return jla.newStringUnsafe(buf); } This version shows ~ 3X speedup, comparing to the current implementation. However, this change does not make the code cleaner. And, as these function do not seem to be performance critical, I'm closing the bug.
01-10-2014

And some more: ./share/classes/javax/net/ssl/SNIServerName.java: private static final char[] HEXES = "0123456789ABCDEF".toCharArray(); ./share/classes/sun/security/krb5/KrbApReq.java: private static final char[] hexConst = "0123456789ABCDEF".toCharArray(); ./share/classes/sun/security/x509/AVA.java: private static final String hexDigits = "0123456789ABCDEF"; ./share/classes/sun/security/pkcs11/wrapper/Functions.java: private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray(); ./java/rmi/dgc/VMID.java: public String toString()
07-08-2014

Another approach would be to introduce another overloaded version of Integer.toString(int x, int radix, int minWidth). minWidth would be set to the minimum number of digits to create. If the number is less, then leading zeroes will be appended. With this in the hands the code above could be rewritten as public static String toString(byte[] b) { return IntStream.range(0, b.length) .mapToObj(x -> Integer.toString((int)b[x] & 0xff, 16, 2)) .collect(Collectors.joining(":")); }
26-05-2014

Two more places to revise: ./share/classes/sun/security/util/Debug.java: private final static char[] hexDigits = "0123456789abcdef".toCharArray(); ./share/classes/sun/security/pkcs11/P11Util.java: private final static char[] hexDigits = "0123456789abcdef".toCharArray();
13-05-2014