RFR: 8317515: Unify the code of the parse*() families of methods in j.l.Integer and j.l.Long [v2]

温绍锦 duke at openjdk.org
Thu Oct 5 12:11:13 UTC 2023


On Thu, 5 Oct 2023 10:31:31 GMT, Raffaello Giulietti <rgiulietti at openjdk.org> wrote:

>> See the [JBS issue](https://bugs.openjdk.org/browse/JDK-8317515) for the details.
>
> Raffaello Giulietti has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Avoid localized integers in radix-out-of-range exception messages.

In fact, the most commonly used one is that radix is 10 and coder is latin1, so we can make a fast-path

public final class Integer {
   public static int parseInt(String s) throws NumberFormatException {
        if (s != null && s.coder() == String.LATIN1) {
            byte[] value = s.value();
            int len = value.length;
            if (len == 0) {
                throw new NumberFormatException("");
            }
            int digit = ~0xFF;
            int i = 0;
            byte firstChar = value[i++];
            if (firstChar != '-' && firstChar != '+') {
                digit = DIGITS[firstChar & 0xFF];
            }
            if (digit >= 0 || digit == ~0xFF && len > 1) {
                int limit = firstChar != '-' ? MIN_VALUE + 1 : MIN_VALUE;
                int multmin = limit / 10;
                int result = -(digit & 0xFF);
                boolean inRange = true;
                /* Accumulating negatively avoids surprises near MAX_VALUE */
                while (i < len && (digit = DIGITS[value[i++] & 0xFF]) >= 0
                        && (inRange = result > multmin
                        || result == multmin && digit <= 10 * multmin - limit)) {
                    result = 10 * result - digit;
                }
                if (inRange && i == len && digit >= 0) {
                    return firstChar != '-' ? -result : result;
                }
            }
            throw NumberFormatException.forInputString(s, 10);
        }
        return parseInt(s, 10);
    }

   @Stable
    private static final byte[] DIGITS = new byte[] {
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
}


Performance numbers running on MacBook M1 Max are about 9% faster:

-Benchmark          (size)  Mode  Cnt  Score   Error  Units
-Integers.parseInt     500  avgt   15  2.480 ? 0.017  us/op

+Benchmark          (size)  Mode  Cnt  Score   Error  Units (fast-path)
+Integers.parseInt     500  avgt   15  2.270 ? 0.011  us/op
``

-------------

PR Comment: https://git.openjdk.org/jdk/pull/16050#issuecomment-1748753625


More information about the core-libs-dev mailing list