Hi Robert; As mentioned in another thread with Steven Schlansker there is a patch in progress with similar goals. I will look at your patch and see how much overlap there is and merge in any relevant parts. This improvement won't make it into Java 8 but will be implemented early in the Java 9 lifecycle and can be backported to Java 8 updates.
Thanks! Mike On Nov 6 2013, at 17:19 , Robert Stupp <sn...@gmx.de> wrote: > Hi, > > the current implementation of java.util.UUID.fromName() and > java.util.UUID.toString() unnecessarily produce a lot of temporary objects. > Especially the fromName() method creates some instances of java.lang.Long and > indirectly via "name.split()" many Strings, an ArrayList, etc. > UUID.toString() creates at least 10 String objects plus the implicitly > created char[] instances. > > Here's a hg diff which reduces the temporary object count while still > providing the same functionality. > > - > Robert > > > > > 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 > @@ -189,23 +189,68 @@ > * > */ > public static UUID fromString(String name) { > - String[] components = name.split("-"); > - if (components.length != 5) > + if (name.length() != 36) > throw new IllegalArgumentException("Invalid UUID string: "+name); > - for (int i=0; i<5; i++) > - components[i] = "0x"+components[i]; > > - long mostSigBits = Long.decode(components[0]).longValue(); > - mostSigBits <<= 16; > - mostSigBits |= Long.decode(components[1]).longValue(); > - mostSigBits <<= 16; > - mostSigBits |= Long.decode(components[2]).longValue(); > + long lo; > + long hi; > + lo = hi = 0; > > - long leastSigBits = Long.decode(components[3]).longValue(); > - leastSigBits <<= 48; > - leastSigBits |= Long.decode(components[4]).longValue(); > + for (int i = 0, j = 0; i < 36; ++j) { > + // Need to bypass hyphens: > > - return new UUID(mostSigBits, leastSigBits); > + switch (i) { > + case 8: > + case 13: > + case 18: > + case 23: > + if (name.charAt(i) != '-') > + throw new IllegalArgumentException("Invalid UUID > string: "+name); > + > + ++i; > + } // switch > + > + int curr; > + char c = name.charAt(i); > + > + if (c >= '0' && c <= '9') > + curr = (c - '0'); > + > + else if (c >= 'a' && c <= 'f') > + curr = (c - 'a' + 10); > + > + else if (c >= 'A' && c <= 'F') > + curr = (c - 'A' + 10); > + > + else > + throw new IllegalArgumentException("Invalid UUID string: > "+name); > + > + curr <<= 4; > + > + c = name.charAt(++i); > + > + if (c >= '0' && c <= '9') > + curr |= (c - '0'); > + > + else if (c >= 'a' && c <= 'f') > + curr |= (c - 'a' + 10); > + > + else if (c >= 'A' && c <= 'F') > + curr |= (c - 'A' + 10); > + > + else > + throw new IllegalArgumentException("Invalid UUID string: > "+name); > + > + if (j < 8) > + hi = (hi << 8) | curr; > + > + else > + lo = (lo << 8) | curr; > + > + ++i; > + } // for > + > + return new UUID(hi, lo); > } > > // Field Accessor Methods > @@ -373,17 +418,27 @@ > * @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[] arr = new char[36]; > + arr[8] = arr[13] = arr[18] = arr[23] = '-'; > + long msb = mostSigBits; > + long lsb = leastSigBits; > + // upper 32 bit of MSB > + digits(msb >> 32, 8, arr, 0); > + // upper 16 bit of lower 32 bit of MSB > + digits(msb >> 16, 4, arr, 9); > + // lower 16 bit of lower 32 bit of MSB > + digits(msb, 4, arr, 14); > + // upper 16 bit of LSB > + digits(lsb, 4, arr, 19); > + // lower 48 bit of LSB > + digits(lsb, 12, arr, 24); > + return new String(arr); > } > > - /** 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 final char[] HEX = > {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; > + private void digits(long v, int digits, char[] arr, int off) { > + for ( ; digits > 0 ; off++ ) > + arr[off] = HEX[ (int)(v&15) ]; > } > > /** > >