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

Print this page
rev 9925 : 8006627: UUID to/from String performance should be improved by reducing object allocations
Reviewed-by: TBD
Contributed-by: Steven Schlansker <stevenschlansker@gmail.com>, Claes Redestad <claes.redestad@oracle.com>

@@ -25,10 +25,13 @@
 
 package java.util;
 
 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.
  *
  * <p> There exist different variants of these global identifiers.  The methods

@@ -86,10 +89,12 @@
      *
      * @serial
      */
     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.
      */
     private static class Holder {

@@ -187,25 +192,28 @@
      *          If name does not conform to the string representation as
      *          described in {@link #toString}
      *
      */
     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);
+
+        if (name.indexOf('-', dash4 + 1) > 0) {
+            throw new IllegalArgumentException("Invalid UUID string: " + name);
+        }
 
-        long mostSigBits = Long.decode(components[0]).longValue();
+        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);
     }
 
     // Field Accessor Methods

@@ -371,21 +379,26 @@
      * }</pre></blockquote>
      *
      * @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));
-    }
-
-    /** 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);
+        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);
+    }
+
+    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);
     }
 
     /**
      * Returns a hash code for this {@code UUID}.
      *