# HG changeset patch # User claes.redestad@oracle.com # Date 1402784330 -7200 # Sun Jun 15 00:18:50 2014 +0200 # Node ID d635d9bf7961889fe8c892b6a95641680a5f4635 # Parent 28d1de89ff27981924765614bd6fb2d981fcc889 8006627: UUID to/from String performance should be improved by reducing object allocations Reviewed-by: TBD Contributed-by: Steven Schlansker , Claes Redestad diff --git a/src/share/classes/java/util/UUID.java b/src/share/classes/java/util/UUID.java --- a/src/share/classes/java/util/UUID.java +++ b/src/share/classes/java/util/UUID.java @@ -27,6 +27,9 @@ import java.security.*; +import sun.misc.JavaLangAccess; +import sun.misc.SharedSecrets; + /** * A class that represents an immutable universally unique identifier (UUID). * A UUID represents a 128-bit value. @@ -88,6 +91,8 @@ */ private final long leastSigBits; + private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); + /* * The random number generator used by this class to create random * based UUIDs. In a holder class to defer initialization until needed. @@ -189,21 +194,24 @@ * */ public static UUID fromString(String name) { - String[] components = name.split("-"); - if (components.length != 5) - throw new IllegalArgumentException("Invalid UUID string: "+name); - for (int i=0; i<5; i++) - components[i] = "0x"+components[i]; + int dash1 = name.indexOf('-', 0); + int dash2 = name.indexOf('-', dash1 + 1); + int dash3 = name.indexOf('-', dash2 + 1); + int dash4 = name.indexOf('-', dash3 + 1); - long mostSigBits = Long.decode(components[0]).longValue(); + if (name.indexOf('-', dash4 + 1) > 0) { + throw new IllegalArgumentException("Invalid UUID string: " + name); + } + + long mostSigBits = jla.parseUnsignedLong(name, 16, 0, dash1) & 0xffffffffL; mostSigBits <<= 16; - mostSigBits |= Long.decode(components[1]).longValue(); + mostSigBits |= jla.parseUnsignedLong(name, 16, dash1 + 1, dash2) & 0xffffL; mostSigBits <<= 16; - mostSigBits |= Long.decode(components[2]).longValue(); + mostSigBits |= jla.parseUnsignedLong(name, 16, dash2 + 1, dash3) & 0xffffL; - long leastSigBits = Long.decode(components[3]).longValue(); + long leastSigBits = jla.parseUnsignedLong(name, 16, dash3 + 1, dash4) & 0xffffL; leastSigBits <<= 48; - leastSigBits |= Long.decode(components[4]).longValue(); + leastSigBits |= jla.parseUnsignedLong(name, 16, dash4 + 1, name.length()) & 0xffffffffffffL; return new UUID(mostSigBits, leastSigBits); } @@ -373,17 +381,22 @@ * @return A string representation of this {@code UUID} */ public String toString() { - return (digits(mostSigBits >> 32, 8) + "-" + - digits(mostSigBits >> 16, 4) + "-" + - digits(mostSigBits, 4) + "-" + - digits(leastSigBits >> 48, 4) + "-" + - digits(leastSigBits, 12)); + char[] chars = new char[36]; + digits(mostSigBits >> 32, chars, 0, 8); + chars[8] = '-'; + digits(mostSigBits >> 16, chars, 9, 4); + chars[13] = '-'; + digits(mostSigBits, chars, 14, 4); + chars[18] = '-'; + digits(leastSigBits >> 48, chars, 19, 4); + chars[23] = '-'; + digits(leastSigBits, chars, 24, 12); + return jla.newStringUnsafe(chars); } - /** Returns val represented by the specified number of hex digits. */ - private static String digits(long val, int digits) { - long hi = 1L << (digits * 4); - return Long.toHexString(hi | (val & (hi - 1))).substring(1); + private static void digits(long val, char[] chars, int offset, int len) { + long hi = 1L << (len * 4); + jla.formatUnsignedLong(hi | (val & (hi - 1)), 4, chars, offset, len); } /**