< prev index next >

src/java.base/share/classes/java/util/UUID.java

Print this page
rev 58210 : 8196334: Optimize UUID#fromString
Reviewed-by: TBD
Contributed-by: plokhotnyuk@gmail.com, jon.chambers@gmail.com, claes.redestad@oracle.com

*** 179,188 **** --- 179,225 ---- md5Bytes[8] |= 0x80; /* set to IETF variant */ return new UUID(md5Bytes); } /** + * Used by {@code fromString}. While {@code Character.digit(ch, 16)} + * could be used to the same effect, benchmarks show specializing + * for ASCII hex is still a small but significant gain. We should + * examine if {@code Character.digit(ch, 16)} can be optimized and + * this code replaced without adding any overhead. + */ + private static final byte[] NIBBLES; + + static { + byte[] ns = new byte[256]; + java.util.Arrays.fill(ns, (byte) -1); + ns['0'] = 0; + ns['1'] = 1; + ns['2'] = 2; + ns['3'] = 3; + ns['4'] = 4; + ns['5'] = 5; + ns['6'] = 6; + ns['7'] = 7; + ns['8'] = 8; + ns['9'] = 9; + ns['A'] = 10; + ns['B'] = 11; + ns['C'] = 12; + ns['D'] = 13; + ns['E'] = 14; + ns['F'] = 15; + ns['a'] = 10; + ns['b'] = 11; + ns['c'] = 12; + ns['d'] = 13; + ns['e'] = 14; + ns['f'] = 15; + NIBBLES = ns; + } + + /** * Creates a {@code UUID} from the string standard representation as * described in the {@link #toString} method. * * @param name * A string that specifies a {@code UUID}
*** 193,202 **** --- 230,274 ---- * If name does not conform to the string representation as * described in {@link #toString} * */ public static UUID fromString(String name) { + if (name.length() == 36) { + char ch1 = name.charAt(8); + char ch2 = name.charAt(13); + char ch3 = name.charAt(18); + char ch4 = name.charAt(23); + if (ch1 == '-' && ch2 == '-' && ch3 == '-' && ch4 == '-') { + long msb1 = parse4Nibbles(name, 0); + long msb2 = parse4Nibbles(name, 4); + long msb3 = parse4Nibbles(name, 9); + long msb4 = parse4Nibbles(name, 14); + long lsb1 = parse4Nibbles(name, 19); + long lsb2 = parse4Nibbles(name, 24); + long lsb3 = parse4Nibbles(name, 28); + long lsb4 = parse4Nibbles(name, 32); + if ((msb1 | msb2 | msb3 | msb4 | lsb1 | lsb2 | lsb3 | lsb4) >= 0) { + return new UUID( + msb1 << 48 | msb2 << 32 | msb3 << 16 | msb4, + lsb1 << 48 | lsb2 << 32 | lsb3 << 16 | lsb4); + } + } + } + return fromString1(name); + } + + private static long parse4Nibbles(String name, int pos) { + byte[] ns = NIBBLES; + char ch1 = name.charAt(pos); + char ch2 = name.charAt(pos + 1); + char ch3 = name.charAt(pos + 2); + char ch4 = name.charAt(pos + 3); + return (ch1 | ch2 | ch3 | ch4) > 0xff ? + -1 : ns[ch1] << 12 | ns[ch2] << 8 | ns[ch3] << 4 | ns[ch4]; + } + + private static UUID fromString1(String name) { int len = name.length(); if (len > 36) { throw new IllegalArgumentException("UUID string too large"); }
< prev index next >