RFR: 8310929: Optimization for Integer.toString [v12]

Roger Riggs rriggs at openjdk.org
Mon Jul 17 21:02:17 UTC 2023


On Mon, 3 Jul 2023 03:49:01 GMT, 温绍锦 <duke at openjdk.org> wrote:

>> Optimization for:
>> Integer.toString
>> Long.toString
>> StringBuilder#append(int)
>> 
>> # Benchmark Result
>> 
>> 
>> sh make/devkit/createJMHBundle.sh
>> bash configure --with-jmh=build/jmh/jars
>> make test TEST="micro:java.lang.Integers.toString*" 
>> make test TEST="micro:java.lang.Longs.toString*" 
>> make test TEST="micro:java.lang.StringBuilders.toStringCharWithInt8"
>> 
>> 
>> ## 1. [aliyun_ecs_c8i.xlarge](https://help.aliyun.com/document_detail/25378.html#c8i)
>> * cpu : intel xeon sapphire rapids (x64)
>> 
>> ``` diff
>> -Benchmark               (size)  Mode  Cnt  Score   Error  Units (baseline)
>> -Integers.toStringBig       500  avgt   15  6.825 ± 0.023  us/op
>> -Integers.toStringSmall     500  avgt   15  4.823 ± 0.023  us/op
>> -Integers.toStringTiny      500  avgt   15  3.878 ± 0.101  us/op
>> 
>> +Benchmark               (size)  Mode  Cnt  Score   Error  Units (PR Update 04 f4aa1989)
>> +Integers.toStringBig       500  avgt   15  6.002 ± 0.054  us/op (+13.71%)
>> +Integers.toStringSmall     500  avgt   15  4.025 ± 0.020  us/op (+19.82%)
>> +Integers.toStringTiny      500  avgt   15  3.874 ± 0.067  us/op (+0.10%)
>> 
>> -Benchmark            (size)  Mode  Cnt  Score   Error  Units (baseline)
>> -Longs.toStringBig       500  avgt   15  9.224 ± 0.021  us/op
>> -Longs.toStringSmall     500  avgt   15  4.621 ± 0.087  us/op
>> 
>> +Benchmark            (size)  Mode  Cnt  Score   Error  Units (PR Update 04 f4aa1989)
>> +Longs.toStringBig       500  avgt   15  7.483 ± 0.018  us/op (+23.26%)
>> +Longs.toStringSmall     500  avgt   15  4.020 ± 0.016  us/op (+14.95%)
>> 
>> -Benchmark                           Mode  Cnt     Score    Error  Units (baseline)
>> -StringBuilders.toStringCharWithInt8 avgt   15    89.327 ±  0.733  ns/op
>> 
>> +Benchmark                            Mode  Cnt   Score   Error  Units (PR Update 04 f4aa1989)
>> +StringBuilders.toStringCharWithInt8  avgt   15  36.639 ± 0.422  ns/op (+143.80%)
>> 
>> 
>> 
>> ## 2. [aliyun_ecs_c8a.xlarge](https://help.aliyun.com/document_detail/25378.html#c8a)
>> * cpu : amd epc genoa (x64)
>> 
>> ``` diff
>> -Benchmark               (size)  Mode  Cnt  Score   Error  Units (baseline)
>> -Integers.toStringBig       500  avgt   15  6.753 ± 0.007  us/op
>> -Integers.toStringSmall     500  avgt   15  4.470 ± 0.005  us/op
>> -Integers.toStringTiny      500  avgt   15  2.764 ± 0.020  us/op
>> 
>> +Benchmark               (size)  Mode  Cnt  Score   Error  Units (PR Update 04 f4aa1989)
>> +Integers.toStringBig       500  avgt   15  5.036 ± 0.005  us/op (+...
>
> 温绍锦 has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Integer/Long toString test against compact strings
>   
>   Co-authored-by: liach <liach at users.noreply.github.com>

src/java.base/share/classes/java/lang/Integer.java line 528:

> 526:             i = q;
> 527:             charPos -= 2;
> 528:             UNSAFE.putShortUnaligned(buf, Unsafe.ARRAY_BYTE_BASE_OFFSET + charPos, PACKED_DIGITS[r], false);

When switching to use Unsafe, `getChars` should do the array bounds check in the loop of the store index.

src/java.base/share/classes/java/lang/Long.java line 559:

> 557:                     Unsafe.ARRAY_BYTE_BASE_OFFSET + charPos,
> 558:                     Integer.PACKED_DIGITS[(int)((q * 100) - i)],
> 559:                     false);

Add the array bound check for the store of the characters.

src/java.base/share/classes/java/lang/Long.java line 584:

> 582:                     Unsafe.ARRAY_BYTE_BASE_OFFSET + charPos,
> 583:                     Integer.PACKED_DIGITS[-i2],
> 584:                     false);

Replace the implicit array bounds check with an explicit array index check if using Unsafe.

src/java.base/share/classes/java/lang/StringUTF16.java line 1595:

> 1593:                     PACKED_DIGITS_UTF16[-i]);
> 1594:         } else {
> 1595:             putChar(buf, --charPos, '0' - i);

Ditto add explicit array bounds check when using Unsafe, especially since the method is used outside of the source file.  Here and in the uses of Unsafe below.

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

PR Review Comment: https://git.openjdk.org/jdk/pull/14699#discussion_r1265892597
PR Review Comment: https://git.openjdk.org/jdk/pull/14699#discussion_r1265893469
PR Review Comment: https://git.openjdk.org/jdk/pull/14699#discussion_r1265894471
PR Review Comment: https://git.openjdk.org/jdk/pull/14699#discussion_r1265895630


More information about the core-libs-dev mailing list