On Mon, 11 Mar 2024 18:03:06 GMT, Shaojin Wen <[email protected]> wrote:
>> The current BigDecimal(String) constructor calls String#toCharArray, which
>> has a memory allocation.
>>
>>
>> public BigDecimal(String val) {
>> this(val.toCharArray(), 0, val.length()); // allocate char[]
>> }
>>
>>
>> When the length is greater than 18, create a char[]
>>
>>
>> boolean isCompact = (len <= MAX_COMPACT_DIGITS); // 18
>> if (!isCompact) {
>> // ...
>> } else {
>> char[] coeff = new char[len]; // allocate char[]
>> // ...
>> }
>>
>>
>> This PR eliminates the two memory allocations mentioned above, resulting in
>> an approximate 60% increase in performance..
>
> Shaojin Wen has updated the pull request incrementally with two additional
> commits since the last revision:
>
> - less duplicate code
> - add more benchmark
I also prefer to reduce duplicate code. There are not many scenarios where
BigDecima(char[]) is used. The most commonly used scenario is
BigDecimal(String).
If performance is very important, the user can implement the parser by himself,
similar to MysqlBinaryValueDecoder#decodeDecimal. He can remove the
StringUtils.toAsciiCharArray conversion and implement the parser based on ascii.
I added some benchmarks, and the numbers show that the performance drops by
21.67% in the SmallCharArray scene, and by 6.52% and 5.69% in the
LargeCharArray and HugeCharArray scenes.
-Benchmark Mode Cnt Score Error
Units #master
-BigDecimals.testConstructorWithSmallCharArray avgt 15 16.488 ? 0.054
ns/op
-BigDecimals.testConstructorWithLargeCharArray avgt 15 90.583 ? 1.523
ns/op
-BigDecimals.testConstructorWithHugeCharArray avgt 15 90.683 ? 1.623
ns/op
-BigDecimals.testConstructorWithCharArray avgt 15 47.418 ? 0.473
ns/op
-BigDecimals.testConstructorWithSmallString avgt 15 19.725 ? 0.049
ns/op
-BigDecimals.testConstructorWithLargeString avgt 15 113.567 ? 1.470
ns/op
-BigDecimals.testConstructorWithHugeString avgt 15 119.712 ? 6.230
ns/op
-BigDecimals.testConstructorWithString avgt 15 67.046 ? 0.979
ns/op
+Benchmark Mode Cnt Score Error
Units (01 #61b5531b)
+BigDecimals.testConstructorWithSmallCharArray avgt 15 14.322 ? 0.063
ns/op +15.12%
+BigDecimals.testConstructorWithLargeCharArray avgt 15 74.090 ? 0.299
ns/op +22.26%
+BigDecimals.testConstructorWithHugeCharArray avgt 15 74.372 ? 0.461
ns/op +21.93%
+BigDecimals.testConstructorWithCharArray avgt 15 41.606 ? 0.284
ns/op +13.96%
+BigDecimals.testConstructorWithSmallString avgt 15 15.019 ? 0.100
ns/op +31.33%
+BigDecimals.testConstructorWithLargeString avgt 15 70.226 ? 0.240
ns/op +61.71%
+BigDecimals.testConstructorWithHugeString avgt 15 70.153 ? 0.455
ns/op +70.64%
+BigDecimals.testConstructorWithString avgt 15 40.064 ? 0.298
ns/op +67.36%
+Benchmark Mode Cnt Score Error
Units (02 #bdf9f4b5)
+BigDecimals.testConstructorWithSmallCharArray avgt 15 21.052 ? 0.109
ns/op -21.67%
+BigDecimals.testConstructorWithLargeCharArray avgt 15 96.911 ? 2.921
ns/op -6.52%
+BigDecimals.testConstructorWithHugeCharArray avgt 15 96.158 ? 3.501
ns/op -5.69%
+BigDecimals.testConstructorWithCharArray avgt 15 54.673 ? 2.563
ns/op -13.26%
+BigDecimals.testConstructorWithSmallString avgt 15 15.061 ? 0.082
ns/op +30.96%
+BigDecimals.testConstructorWithLargeString avgt 15 70.670 ? 0.607
ns/op +60.70%
+BigDecimals.testConstructorWithHugeString avgt 15 70.706 ? 0.531
ns/op +69.30%
+BigDecimals.testConstructorWithString avgt 15 39.869 ? 0.149
ns/op +68.16%
-------------
PR Comment: https://git.openjdk.org/jdk/pull/18177#issuecomment-1989144767