RFR: 8366224: Introduce DecimalDigits.appendPair for efficient two-digit formatting and refactor DateTimeHelper [v22]
Shaojin Wen
swen at openjdk.org
Fri Nov 14 05:20:14 UTC 2025
On Fri, 14 Nov 2025 04:46:26 GMT, Shaojin Wen <swen at openjdk.org> wrote:
>> This PR introduces a new efficient API for appending two-digit integers to StringBuilders and refactors DateTimeHelper to leverage this new functionality.
>>
>> Changes include:
>>
>> 1. New `appendPair` method for efficient two-digit integer formatting (00-99):
>> - Added `AbstractStringBuilder.appendLatin1(char c1, char c2)` with core implementation
>> - Added `JavaLangAccess.appendPair(StringBuilder, char c1, char c2)` for internal access
>> - Added `DecimalDigits.appendPair(StringBuilder, int)` public static utility method
>> - Enhanced Javadoc documentation for all new methods
>>
>> 2. Refactored `DateTimeHelper` to use the new `DecimalDigits.appendPair`:
>> - Updated `DateTimeHelper.formatTo` methods for `LocalDate` and `LocalTime`
>> - Replaced manual formatting logic with the new efficient two-digit appending
>> - Improved code clarity and consistency in date/time formatting
>>
>> These changes improve code clarity and performance when formatting two-digit numbers, particularly in date/time formatting scenarios.
>
> Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision:
>
> remove JLA
In the current version 35b98cb891207af7eaaa42503c0c872ec68771c6, run the following test:
make test TEST="micro:java.time.ToStringBench.localDateToString" MICRO="VM_OPTIONS=-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=TraceMergeStores,jdk.internal.util.DecimalDigits::appendQuad,SUCCESS"
The output is as follows:
[TraceMergeStores]: Replace
841 StoreB === 881 806 833 53 [[ 846 ]] @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7; Memory: @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;
846 StoreB === 881 841 844 129 [[ 851 ]] @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7; Memory: @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;
[TraceMergeStores]: with
53 LoadS === 5 7 51 [[ 129 615 533 871 841 515 303 649 689 902 ]] @short[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #short !jvms: DecimalDigits::appendQuad @ bci:10 (line 491)
902 StoreC === 881 806 833 53 [[ ]] @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7; mismatched Memory: @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;
[TraceMergeStores]: Replace
851 StoreB === 881 902 849 78 [[ 856 ]] @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7; Memory: @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;
856 StoreB === 881 851 854 142 [[ 873 ]] @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7; Memory: @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;
[TraceMergeStores]: with
78 LoadS === 5 7 76 [[ 142 533 615 865 851 515 303 649 689 903 ]] @short[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #short !jvms: DecimalDigits::appendQuad @ bci:22 (line 492)
903 StoreC === 881 902 849 78 [[ ]] @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7; mismatched Memory: @byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;
We can see there are two `SotreC` instructions here. Is it possible to merge these into OrI + StoreI, writing 4 bytes at a time?
@eme64
In version 57ef68f4e49561423131287556cd592e29f05ba8, which uses JLA.appendLantin1, it can be optimized to OrI + StoreI.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/26911#issuecomment-3530872741
More information about the core-libs-dev
mailing list