RFR: 8315585: Optimization for decimal to string [v6]
Shaojin Wen
swen at openjdk.org
Fri Dec 19 06:14:57 UTC 2025
On Mon, 15 Dec 2025 23:30:06 GMT, Chen Liang <liach at openjdk.org> wrote:
>> Shaojin Wen has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 37 commits:
>>
>> - Merge remote-tracking branch 'upstream/master' into dec_to_str_202501
>> - simplify layoutChars
>> - comments, from @liach
>> - getValueString -> getCompactValueString, from @liach
>> - Refactor BigDecimal string creation to use JLA.uncheckedNewStringWithLatin1Bytes
>>
>> Co-authored-by: Qwen-Coder <qwen-coder at alibabacloud.com>
>> - Merge remote-tracking branch 'upstream/master' into dec_to_str_202501
>>
>> # Conflicts:
>> # src/java.base/share/classes/java/math/BigDecimal.java
>> - Merge remote-tracking branch 'upstream/master' into dec_to_str_202501
>>
>> # Conflicts:
>> # src/java.base/share/classes/java/math/BigDecimal.java
>> # src/java.base/share/classes/jdk/internal/util/DecimalDigits.java
>> # test/micro/org/openjdk/bench/java/math/BigDecimals.java
>> - Merge remote-tracking branch 'upstream/master' into dec_to_str_202501
>> - Merge remote-tracking branch 'upstream/master' into dec_to_str_202501
>>
>> # Conflicts:
>> # src/java.base/share/classes/jdk/internal/util/DecimalDigits.java
>> - remove getChars(long, int, char[])
>> - ... and 27 more: https://git.openjdk.org/jdk/compare/3f33eaa4...32d95b36
>
> src/java.base/share/classes/java/math/BigDecimal.java line 4237:
>
>> 4235: if (coeffLen > 1) { // more to come
>> 4236: buf.append('.')
>> 4237: .append(coeff, 1, coeffLen);
>
> Is this right that the old end is `coeffLen - 1` but the new end is `coeffLen`? I don't see why there should be no more `-1`.
If we use `new BigDecimal("4.933579065397471E-11").toString()` as an example:
In the original code, `coeff` is generated as follows, with three unused null values before the `char[]`:
coeff = new char[19];
offset = DecimalDigits.getChars(Math.abs(intCompact), coeff.length, coeff);
The code that was called:
// coeff := [, , , 4, 9, 3, 3, 5, 7, 9, 0, 6, 5, 3, 9, 7, 4, 7, 1]
// offset := 3
// coeffLen := 16
// append(char[] str, int offset, int len)
buf.append(coeff, offset + 1, coeffLen - 1);
In the new code, coeff is generated as follows:
byte[] buf = new byte[coeffLen];
DecimalDigits.uncheckedGetCharsLatin1(intCompactAbs, buf.length, buf);
coeff = newStringNoRepl(buf);
The method call has also been changed from `append(char[] str, int offset, int len)` to `append(CharSequence s, int start, int end)`.
// coeff := "4933579065397471"
// coeffLen := 16
// append(CharSequence s, int start, int end)
buf.append(coeff, 1, coeffLen);
| | origin | current |
|---------------|----------------------------------------------------------------------------|--------------------|
| coeoff | [ 0x00, 0x00, 0x00, 4, 9, 3, 3, 5, 7, 9, 0, 6, 5, 3, 9, 7, 4, 7, 1] | "4933579065397471" |
| offset | 3 | |
| coeffLen | 16 | 16 |
| call method | append(char[] str, int offset, int len) | append(CharSequence s, int start, int end) |
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/23310#discussion_r2633331853
More information about the core-libs-dev
mailing list