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) ];
>     }
> 
>     /**
> 
> 

Reply via email to