-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8343962: [REDO] Move getChars to DecimalDigits #22023
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back swen! A progress list of the required criteria for merging this PR into |
@wenshao This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 83 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
@wenshao The following labels will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
@wenshao you need a new JBS issue to complete this work under. |
/label remove security hotspot-compiler |
@wenshao The |
} | ||
|
||
private static void putCharUTF16(byte[] buf, int charPos, int c) { | ||
UNSAFE.putChar(buf, ARRAY_BYTE_BASE_OFFSET + ((long) charPos << 1), (char) c); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we can put a char
into a byte[]
.
@cl4es is this safe on all platforms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc of Unsafe::putChar()
delegates to the doc of Unsafe::putInt()
which clearly states that the Object
and offset
arguments must locate a variable of the same type as the one of argument x
, which is not the case here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is safe. See
jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template
Lines 129 to 132 in 3804082
return UNSAFE.get$Type$Unaligned( | |
ba, | |
((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET, | |
handle.be); |
MethodHandles.byteArrayViewVarHandle
implementation does getChar/Short/Int/Long on a byte array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference there is the use of Unsafe.get/putCharUnaligned
. I think putChar
might work for all current platforms and modes since we're always storing at an index that is divisible by 2 in the byte array, thus aligned up to char
. That said this might be an abuse of an unspecified behavior and adding -Unaligned
might be a bit safer.
The performance numbers below show a significant improvement for appendWithIntLatin1 and appendWithLongLatin1. However, for appendWithIntUtf16 and appendWithLongUtf16, the performance is variable, sometimes faster and sometimes slower. This inconsistency might be due to measurement errors or other factors. 1. Scriptgit remote add wenshao git@github.com:wenshao/jdk.git
git fetch wenshao
# baseline d9e4383cca7
git checkout d9e4383cca77ed9667ea6916624f6416f976e3bf
make test TEST="micro:java.lang.StringBuilders.appendWithInt"
make test TEST="micro:java.lang.StringBuilders.appendWithLong"
# current be1f88abfa5
git checkout be1f88abfa505b08bda761317961fef9b79986fe
make test TEST="micro:java.lang.StringBuilders.appendWithInt"
make test TEST="micro:java.lang.StringBuilders.appendWithLong" 2. aliyun_ecs_c8a_x64 (CPU AMD EPYC™ Genoa)-Benchmark Mode Cnt Score Error Units (d9e4383cca7)
-StringBuilders.appendWithIntLatin1 avgt 15 171.264 ± 2.500 ns/op
-StringBuilders.appendWithIntUtf16 avgt 15 162.430 ± 1.829 ns/op
-StringBuilders.appendWithLongLatin1 avgt 15 227.369 ± 1.452 ns/op
-StringBuilders.appendWithLongUtf16 avgt 15 214.854 ± 0.495 ns/op
+Benchmark Mode Cnt Score Error Units (be1f88abfa5)
+StringBuilders.appendWithIntLatin1 avgt 15 136.149 ± 0.213 ns/op +25.79%
+StringBuilders.appendWithIntUtf16 avgt 15 165.650 ± 0.762 ns/op -1.94%
+StringBuilders.appendWithLongLatin1 avgt 15 190.156 ± 2.260 ns/op +19.56%
+StringBuilders.appendWithLongUtf16 avgt 15 224.880 ± 0.389 ns/op -4.45%
3. aliyun_ecs_c8i_x64 (CPU Intel®Xeon®Emerald Rapids)-Benchmark Mode Cnt Score Error Units (d9e4383cca7)
-StringBuilders.appendWithIntLatin1 avgt 15 176.098 ± 3.122 ns/op
-StringBuilders.appendWithIntUtf16 avgt 15 162.548 ± 0.403 ns/op
-StringBuilders.appendWithLongLatin1 avgt 15 225.868 ± 1.912 ns/op
-StringBuilders.appendWithLongUtf16 avgt 15 201.952 ± 6.429 ns/op
+Benchmark Mode Cnt Score Error Units (be1f88abfa5)
+StringBuilders.appendWithIntLatin1 avgt 15 145.052 ± 0.633 ns/op +21.40%
+StringBuilders.appendWithIntUtf16 avgt 15 166.678 ± 0.392 ns/op -2.47%
+StringBuilders.appendWithLongLatin1 avgt 15 187.617 ± 1.750 ns/op +20.38%
+StringBuilders.appendWithLongUtf16 avgt 15 214.047 ± 1.687 ns/op -5.65% 4. aliyun_ecs_c8y_aarch64 (CPU Aliyun Yitian 710 ARM v9)-Benchmark Mode Cnt Score Error Units (d9e4383cca7)
-StringBuilders.appendWithIntLatin1 avgt 15 267.675 ± 0.180 ns/op
-StringBuilders.appendWithIntUtf16 avgt 15 246.470 ± 0.896 ns/op
-StringBuilders.appendWithLongLatin1 avgt 15 342.262 ± 0.292 ns/op
-StringBuilders.appendWithLongUtf16 avgt 15 327.840 ± 0.565 ns/op
+Benchmark Mode Cnt Score Error Units (be1f88abfa5)
+StringBuilders.appendWithIntLatin1 avgt 15 239.923 ± 1.331 ns/op +11.56%
+StringBuilders.appendWithIntUtf16 avgt 15 252.083 ± 2.270 ns/op -2.22%
+StringBuilders.appendWithLongLatin1 avgt 15 294.602 ± 2.770 ns/op +16.17%
+StringBuilders.appendWithLongUtf16 avgt 15 324.465 ± 0.498 ns/op +1.04%
5. MacBook M1 Pro (aarch64)-Benchmark Mode Cnt Score Error Units (d9e4383cca7)
-StringBuilders.appendWithIntLatin1 avgt 15 183.633 ? 5.675 ns/op
-StringBuilders.appendWithIntUtf16 avgt 15 156.111 ? 1.045 ns/op
-StringBuilders.appendWithLongLatin1 avgt 15 246.320 ? 0.934 ns/op
-StringBuilders.appendWithLongUtf16 avgt 15 222.053 ? 1.177 ns/op
+Benchmark Mode Cnt Score Error Units (be1f88abfa5)
+StringBuilders.appendWithIntLatin1 avgt 15 139.442 ? 0.488 ns/op +31.69%
+StringBuilders.appendWithIntUtf16 avgt 15 155.319 ? 1.039 ns/op +0.50%
+StringBuilders.appendWithLongLatin1 avgt 15 202.335 ? 2.133 ns/op +21.73%
+StringBuilders.appendWithLongUtf16 avgt 15 223.250 ? 0.774 ns/op -0.53%
6. orange_pi5_aarch64 (CPU RK3588S ARMv8.4)-Benchmark Mode Cnt Score Error Units (d9e4383cca7)
-StringBuilders.appendWithIntLatin1 avgt 15 460.837 ± 6.925 ns/op
-StringBuilders.appendWithIntUtf16 avgt 15 482.623 ± 16.269 ns/op
-StringBuilders.appendWithLongLatin1 avgt 15 653.808 ± 15.051 ns/op
-StringBuilders.appendWithLongUtf16 avgt 15 619.189 ± 15.581 ns/op
+Benchmark Mode Cnt Score Error Units
+StringBuilders.appendWithIntLatin1 avgt 15 385.403 ± 5.387 ns/op +19.57%
+StringBuilders.appendWithIntUtf16 avgt 15 439.273 ± 3.404 ns/op +9.86%
+StringBuilders.appendWithLongLatin1 avgt 15 573.817 ± 20.499 ns/op +13.94%
+StringBuilders.appendWithLongUtf16 avgt 15 661.942 ± 0.282 ns/op -6.45%
|
Yes, that's what I observe as well. Your M1 results are consistent with the one I published just a few minutes earlier, so that's good. Do you think it is worth reconsidering the UTF16 case, which is mostly slightly slower? If not, I will approve the PR. |
The UTF16 case is slower on x64 machines, and I think it's worth analyzing why. |
Do you prefer to postpone that analysis to a followup PR, so that we can integrate this one and move on? |
Thanks @rgiulietti I found out that the reason for the slowdown on x64 may not be related to the changes in this PR, because I reverted the code to (d22a286) in the current PR branch, and the performance is the same. I suspect that the master version C2 has new optimizations. I think it can be integrated, and further optimization can be put in the next step. My next optimization plan is to change the length of DIGITS to 128 and use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @wenshao for your contribution.
@cl4es I think you need to re-review for this PR to move to 100% approved |
@cl4es FYI, the changes introduced since the commit you approved are just cosmetic and stylistic. The only notable modification is the use of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks good.
(I'm on temporary leave, sorry for the late response)
/integrate |
Going to push as commit f446cef.
Your commit was automatically rebased without conflicts. |
This PR is a resubmission after PR #21593 was rolled back, and the unsafe offset overflow issue has been fixed.
Move getChars methods of StringLatin1 and StringUTF16 to DecimalDigits to reduce duplication.
HexDigits and OctalDigits also include getCharsLatin1 and getCharsUTF16
Putting these two methods into DecimalDigits can avoid the need to expose them in JavaLangAccess
Eliminate duplicate code in BigDecimal
This PR will improve the performance of Integer/Long.toString and StringBuilder.append(int/long) scenarios. This is because Unsafe.putByte is used to eliminate array bounds checks, and of course this elimination is safe. In previous versions, in Integer/Long.toString and StringBuilder.append(int/long) scenarios, -COMPACT_STRING performed better than +COMPACT_STRING. This is because StringUTF16.getChars uses StringUTF16.putChar, which is similar to Unsafe.putChar, and there is no bounds check.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/22023/head:pull/22023
$ git checkout pull/22023
Update a local copy of the PR:
$ git checkout pull/22023
$ git pull https://git.openjdk.org/jdk.git pull/22023/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 22023
View PR using the GUI difftool:
$ git pr show -t 22023
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/22023.diff
Using Webrev
Link to Webrev Comment