On Mon, 4 Sep 2023 04:58:08 GMT, 温绍锦 <[email protected]> wrote:
> BigDecimal is a commonly used class in business development, It is often
> necessary to perform toString or toPlainString operations on BigDecimal.
>
> The current version uses StringBuilder resulting in multiple memory
> allocations, I made a modification to improve performance.
>
> Because BigDecimal uses stringCache to cache the result of toString, the
> performance of toString needs special treatment before testing, such as
> clearing stringCache by unsafe operation before each test, The performance of
> toString is similar to that of toEngineering.
>
> The performance data is as follows:
>
> ## 1. benchmark script
>
> sh make/devkit/createJMHBundle.sh
> bash configure --with-jmh=build/jmh/jars
> make test TEST="micro:java.math.BigDecimals.*ToPlainString"
> make test TEST="micro:java.math.BigDecimals.*ToEngineering"
>
>
> ## 2. benchmark environment
> * virtual machine :
> [aliyun_ecs_c8i.xlarge](https://help.aliyun.com/zh/ecs/user-guide/overview-of-instance-families#c8i)
> * cpu intel xeon sapphire rapids (x64)
>
> ## 3. benchmark result
>
> -BigDecimals.testHugeToPlainString avgt 15 188.691 ± 0.822
> ns/op (baseline)
> -BigDecimals.testLargeToPlainString avgt 15 36.656 ± 0.065 ns/op
> -BigDecimals.testSmallToPlainString avgt 15 34.342 ± 0.068 ns/op
> -BigDecimals.testToPlainString avgt 15 1719.494 ± 24.886 ns/op
>
> +Benchmark Mode Cnt Score Error
> Units (optimize)
> +BigDecimals.testHugeToPlainString avgt 15 133.972 ? 0.328
> ns/op (+40.84%)
> +BigDecimals.testLargeToPlainString avgt 15 14.957 ? 0.047
> ns/op (145.07%)
> +BigDecimals.testSmallToPlainString avgt 15 12.045 ? 0.036
> ns/op (+185.11)
> +BigDecimals.testToPlainString avgt 15 1643.500 ? 3.217
> ns/op (+4.62%)
>
> -Benchmark Mode Cnt Score Error
> Units (baseline)
> -BigDecimals.testHugeToEngineeringString avgt 15 207.621 ± 5.018 ns/op
> -BigDecimals.testLargeToEngineeringString avgt 15 35.658 ± 3.144 ns/op
> -BigDecimals.testSmallToEngineeringString avgt 15 15.142 ± 0.053 ns/op
> -BigDecimals.testToEngineeringString avgt 15 1813.959 ± 12.842 ns/op
>
> +Benchmark Mode Cnt Score Error
> Units (optimize)
> +BigDecimals.testHugeToEngineeringString avgt 15 142.110 ? 0.987
> ns/op (+45.09%)
> +BigDecimals.testLargeToEngineeringString avgt 15 12.509 ? 0.056
> ns/op (+185.05%)
> +BigDecimals.testSmallToEngineer...
src/java.base/share/classes/java/math/BigInteger.java line 4104:
> 4102: byte[] buf = smallToString(signum < 0, abs);
> 4103: try {
> 4104: return BigDecimal.jla.newStringNoRepl(buf,
> StandardCharsets.ISO_8859_1);
The usages of `BigDecimal.jla` and its String computation methods may trigger
initialization of BigDecimal when using BigInteger. I recommend moving these
string computation utilities and the jla field to a new package-private class
within java.math (or a new class in jdk.internal.math package) to prevent
initializing BigDecimal unnecessarily.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/15555#discussion_r1315408192