8196334: Optimize UUID#fromString

Co-authored-by: Andriy Plokhotnyuk <plokhotnyuk@gmail.com>
Co-authored-by: Jon Chambers <jon.chambers@gmail.com>
Reviewed-by: igerasim, alanb
This commit is contained in:
Claes Redestad 2020-03-02 08:22:48 +01:00
parent 751de03704
commit ebadfaeb2e
3 changed files with 145 additions and 5 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -180,6 +180,45 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
return new UUID(md5Bytes);
}
private static final byte[] NIBBLES;
static {
byte[] ns = new byte[256];
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;
}
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];
}
/**
* Creates a {@code UUID} from the string standard representation as
* described in the {@link #toString} method.
@ -195,6 +234,31 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
*
*/
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 UUID fromString1(String name) {
int len = name.length();
if (len > 36) {
throw new IllegalArgumentException("UUID string too large");