RFR: 8336856: Optimize String Concat [v22]
Shaojin Wen
duke at openjdk.org
Thu Aug 1 23:43:33 UTC 2024
On Wed, 31 Jul 2024 22:27:53 GMT, Shaojin Wen <duke at openjdk.org> wrote:
>> The current implementation of StringConcat is to mix the coder and length into a long. This operation will have some overhead for int/long/boolean types. We can separate the calculation of the coder from the calculation of the length, which can improve the performance in the scenario of concat int/long/boolean.
>>
>> This idea comes from the suggestion of @l4es in the discussion of PR https://github.com/openjdk/jdk/pull/20253#issuecomment-2240412866
>
> Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision:
>
> use ClassFile ACC Flags
Below are the performance numbers running on a MacBook M1 Pro. current2 is implemented completely with the new bytecode using `-Djava.lang.invoke.StringConcat.highArityThreshold=0`.
-# baseline 5ff7c57f9ff5428ef3d2aedd7e860bb1e8ff29ea
-Benchmark (intValue) Mode Cnt Score Error Units
-StringConcat.concat123String 4711 avgt 15 990.214 ? 1.890 ns/op
-StringConcat.concat13String 4711 avgt 15 45.810 ? 0.163 ns/op
-StringConcat.concat13StringConst 4711 avgt 15 75.283 ? 4.831 ns/op
-StringConcat.concat23String 4711 avgt 15 90.812 ? 0.317 ns/op
-StringConcat.concat23StringConst 4711 avgt 15 101.114 ? 0.201 ns/op
-StringConcat.concat30Mix 4711 avgt 15 262.114 ? 20.685 ns/op
-StringConcat.concat3String 4711 avgt 15 12.607 ? 0.222 ns/op
-StringConcat.concat4String 4711 avgt 15 13.935 ? 0.181 ns/op
-StringConcat.concat6String 4711 avgt 15 19.831 ? 0.474 ns/op
-StringConcat.concatConst2String 4711 avgt 15 9.491 ? 0.134 ns/op
-StringConcat.concatConst4String 4711 avgt 15 14.786 ? 0.087 ns/op
-StringConcat.concatConst6Object 4711 avgt 15 51.650 ? 0.314 ns/op
-StringConcat.concatConst6String 4711 avgt 15 19.553 ? 0.054 ns/op
-StringConcat.concatConstBool 4711 avgt 15 3.439 ? 0.020 ns/op
-StringConcat.concatConstBoolByte 4711 avgt 15 6.440 ? 0.024 ns/op
-StringConcat.concatConstBoolString 4711 avgt 15 7.054 ? 0.059 ns/op
-StringConcat.concatConstBoolean 4711 avgt 15 3.965 ? 0.009 ns/op
-StringConcat.concatConstBooleanString 4711 avgt 15 7.298 ? 0.021 ns/op
-StringConcat.concatConstFloat 4711 avgt 15 58.590 ? 2.390 ns/op
-StringConcat.concatConstFloatString 4711 avgt 15 59.409 ? 1.320 ns/op
-StringConcat.concatConstInt 4711 avgt 15 6.074 ? 0.006 ns/op
-StringConcat.concatConstIntConstInt 4711 avgt 15 9.726 ? 0.126 ns/op
-StringConcat.concatConstIntString 4711 avgt 15 15.178 ? 0.642 ns/op
-StringConcat.concatConstInteger 4711 avgt 15 4.002 ? 0.015 ns/op
-StringConcat.concatConstIntegerString 4711 avgt 15 7.040 ? 0.207 ns/op
-StringConcat.concatConstString 4711 avgt 15 4.983 ? 0.019 ns/op
-StringConcat.concatConstStringConstInt 4711 avgt 15 11.906 ? 1.898 ns/op
-StringConcat.concatEmptyConstInt 4711 avgt 15 5.618 ? 0.023 ns/op
-StringConcat.concatEmptyConstString 4711 avgt 15 2.058 ? 0.037 ns/op
-StringConcat.concatEmptyLeft 4711 avgt 15 2.216 ? 0.012 ns/op
-StringConcat.concatEmptyRight 4711 avgt 15 2.373 ? 0.011 ns/op
-StringConcat.concatMethodConstString 4711 avgt 15 4.973 ? 0.008 ns/op
-StringConcat.concatMix4String 4711 avgt 15 84.747 ? 6.062 ns/op
-StringConcat.concatStringBoolString 4711 avgt 15 18.836 ? 4.729 ns/op
-StringConcat.concatStringBooleanString 4711 avgt 15 9.878 ? 0.087 ns/op
-StringConcat.concatStringIntString 4711 avgt 15 18.083 ? 0.492 ns/op
-StringConcat.concatStringIntegerString 4711 avgt 15 9.099 ? 0.126 ns/op
-StringConcatStartup.MixedLarge.run N/A ss 10 315.546 ? 14.083 ms/op
-StringConcatStartup.MixedSmall.run N/A ss 20 24.704 ? 0.621 ms/op
-StringConcatStartup.StringLarge.run N/A ss 10 87.007 ? 5.414 ms/op
-StringConcatStartup.StringSingle.constBool 4711 ss 40 2.102 ? 0.068 ms/op
-StringConcatStartup.StringSingle.constBoolString 4711 ss 40 0.261 ? 0.010 ms/op
-StringConcatStartup.StringSingle.constBoolean 4711 ss 40 0.147 ? 0.010 ms/op
-StringConcatStartup.StringSingle.constBooleanString 4711 ss 40 3.506 ? 0.090 ms/op
-StringConcatStartup.StringSingle.constFloat 4711 ss 40 2.628 ? 0.074 ms/op
-StringConcatStartup.StringSingle.constFloatString 4711 ss 40 4.473 ? 0.094 ms/op
-StringConcatStartup.StringSingle.constInt 4711 ss 40 2.022 ? 0.070 ms/op
-StringConcatStartup.StringSingle.constIntString 4711 ss 40 0.150 ? 0.005 ms/op
-StringConcatStartup.StringSingle.constInteger 4711 ss 40 0.144 ? 0.008 ms/op
-StringConcatStartup.StringSingle.constIntegerString 4711 ss 40 3.541 ? 0.117 ms/op
-StringConcatStartup.StringSingle.constString 4711 ss 40 0.138 ? 0.009 ms/op
-StringConcatStartup.StringThree.stringIntString 4711 ss 40 6.166 ? 0.149 ms/op
-StringConcatStartup.StringThree.stringIntegerString 4711 ss 40 5.123 ? 0.127 ms/op
+# current d573c297219115976ad03f70fbd7777aedc3d4b8
+Benchmark (intValue) Mode Cnt Score Error Units
+StringConcat.concat123String 4711 avgt 15 980.749 ? 10.562 ns/op
+StringConcat.concat13String 4711 avgt 15 46.520 ? 0.509 ns/op
+StringConcat.concat13StringConst 4711 avgt 15 71.920 ? 0.335 ns/op
+StringConcat.concat23String 4711 avgt 15 93.629 ? 0.249 ns/op
+StringConcat.concat23StringConst 4711 avgt 15 110.605 ? 0.171 ns/op
+StringConcat.concat30Mix 4711 avgt 15 376.001 ? 36.738 ns/op
+StringConcat.concat3String 4711 avgt 15 12.492 ? 0.228 ns/op
+StringConcat.concat4String 4711 avgt 15 13.968 ? 0.134 ns/op
+StringConcat.concat6String 4711 avgt 15 19.758 ? 0.477 ns/op
+StringConcat.concatConst2String 4711 avgt 15 9.479 ? 0.121 ns/op
+StringConcat.concatConst4String 4711 avgt 15 14.800 ? 0.046 ns/op
+StringConcat.concatConst6Object 4711 avgt 15 51.606 ? 0.389 ns/op
+StringConcat.concatConst6String 4711 avgt 15 19.513 ? 0.057 ns/op
+StringConcat.concatConstBool 4711 avgt 15 3.465 ? 0.043 ns/op
+StringConcat.concatConstBoolByte 4711 avgt 15 6.431 ? 0.025 ns/op
+StringConcat.concatConstBoolString 4711 avgt 15 7.030 ? 0.022 ns/op
+StringConcat.concatConstBoolean 4711 avgt 15 3.965 ? 0.016 ns/op
+StringConcat.concatConstBooleanString 4711 avgt 15 7.308 ? 0.019 ns/op
+StringConcat.concatConstFloat 4711 avgt 15 58.247 ? 1.906 ns/op
+StringConcat.concatConstFloatString 4711 avgt 15 60.221 ? 1.932 ns/op
+StringConcat.concatConstInt 4711 avgt 15 6.080 ? 0.012 ns/op
+StringConcat.concatConstIntConstInt 4711 avgt 15 9.800 ? 0.131 ns/op
+StringConcat.concatConstIntString 4711 avgt 15 14.696 ? 0.146 ns/op
+StringConcat.concatConstInteger 4711 avgt 15 4.006 ? 0.038 ns/op
+StringConcat.concatConstIntegerString 4711 avgt 15 6.922 ? 0.020 ns/op
+StringConcat.concatConstString 4711 avgt 15 4.992 ? 0.050 ns/op
+StringConcat.concatConstStringConstInt 4711 avgt 15 11.693 ? 1.738 ns/op
+StringConcat.concatEmptyConstInt 4711 avgt 15 5.628 ? 0.029 ns/op
+StringConcat.concatEmptyConstString 4711 avgt 15 2.065 ? 0.024 ns/op
+StringConcat.concatEmptyLeft 4711 avgt 15 2.231 ? 0.017 ns/op
+StringConcat.concatEmptyRight 4711 avgt 15 2.398 ? 0.014 ns/op
+StringConcat.concatMethodConstString 4711 avgt 15 5.013 ? 0.012 ns/op
+StringConcat.concatMix4String 4711 avgt 15 80.071 ? 1.992 ns/op
+StringConcat.concatStringBoolString 4711 avgt 15 19.235 ? 1.379 ns/op
+StringConcat.concatStringBooleanString 4711 avgt 15 9.780 ? 0.099 ns/op
+StringConcat.concatStringIntString 4711 avgt 15 18.258 ? 0.515 ns/op
+StringConcat.concatStringIntegerString 4711 avgt 15 9.161 ? 0.191 ns/op
+StringConcatStartup.MixedLarge.run N/A ss 10 310.811 ? 12.045 ms/op
+StringConcatStartup.MixedSmall.run N/A ss 20 24.526 ? 0.702 ms/op
+StringConcatStartup.StringLarge.run N/A ss 10 86.733 ? 3.614 ms/op
+StringConcatStartup.StringSingle.constBool 4711 ss 40 2.139 ? 0.074 ms/op
+StringConcatStartup.StringSingle.constBoolString 4711 ss 40 0.267 ? 0.010 ms/op
+StringConcatStartup.StringSingle.constBoolean 4711 ss 40 0.144 ? 0.009 ms/op
+StringConcatStartup.StringSingle.constBooleanString 4711 ss 40 3.610 ? 0.082 ms/op
+StringConcatStartup.StringSingle.constFloat 4711 ss 40 2.683 ? 0.090 ms/op
+StringConcatStartup.StringSingle.constFloatString 4711 ss 40 4.491 ? 0.109 ms/op
+StringConcatStartup.StringSingle.constInt 4711 ss 40 2.073 ? 0.075 ms/op
+StringConcatStartup.StringSingle.constIntString 4711 ss 40 0.158 ? 0.008 ms/op
+StringConcatStartup.StringSingle.constInteger 4711 ss 40 0.146 ? 0.009 ms/op
+StringConcatStartup.StringSingle.constIntegerString 4711 ss 40 3.640 ? 0.070 ms/op
+StringConcatStartup.StringSingle.constString 4711 ss 40 0.147 ? 0.010 ms/op
+StringConcatStartup.StringThree.stringIntString 4711 ss 40 6.189 ? 0.131 ms/op
+StringConcatStartup.StringThree.stringIntegerString 4711 ss 40 5.250 ? 0.129 ms/op
+# current2 d573c297219115976ad03f70fbd7777aedc3d4b8
+# MICRO="VM_OPTIONS=-Djava.lang.invoke.StringConcat.highArityThreshold=0"
+Benchmark (intValue) Mode Cnt Score Error Units
+StringConcat.concat123String 4711 avgt 15 973.317 ? 0.981 ns/op
+StringConcat.concat13String 4711 avgt 15 44.808 ? 0.051 ns/op
+StringConcat.concat13StringConst 4711 avgt 15 67.801 ? 0.939 ns/op
+StringConcat.concat23String 4711 avgt 15 93.563 ? 0.285 ns/op
+StringConcat.concat23StringConst 4711 avgt 15 110.992 ? 0.368 ns/op
+StringConcat.concat30Mix 4711 avgt 15 369.601 ? 29.285 ns/op
+StringConcat.concat3String 4711 avgt 15 11.885 ? 0.114 ns/op
+StringConcat.concat4String 4711 avgt 15 13.974 ? 0.219 ns/op
+StringConcat.concat6String 4711 avgt 15 19.828 ? 0.510 ns/op
+StringConcat.concatConst2String 4711 avgt 15 9.505 ? 0.111 ns/op
+StringConcat.concatConst4String 4711 avgt 15 14.818 ? 0.100 ns/op
+StringConcat.concatConst6Object 4711 avgt 15 82.329 ? 0.275 ns/op
+StringConcat.concatConst6String 4711 avgt 15 22.217 ? 0.033 ns/op
+StringConcat.concatConstBool 4711 avgt 15 3.431 ? 0.029 ns/op
+StringConcat.concatConstBoolByte 4711 avgt 15 6.573 ? 0.021 ns/op
+StringConcat.concatConstBoolString 4711 avgt 15 7.016 ? 0.018 ns/op
+StringConcat.concatConstBoolean 4711 avgt 15 3.971 ? 0.017 ns/op
+StringConcat.concatConstBooleanString 4711 avgt 15 7.336 ? 0.046 ns/op
+StringConcat.concatConstFloat 4711 avgt 15 58.261 ? 1.530 ns/op
+StringConcat.concatConstFloatString 4711 avgt 15 59.223 ? 0.967 ns/op
+StringConcat.concatConstInt 4711 avgt 15 6.103 ? 0.016 ns/op
+StringConcat.concatConstIntConstInt 4711 avgt 15 9.839 ? 0.148 ns/op
+StringConcat.concatConstIntString 4711 avgt 15 15.349 ? 0.537 ns/op
+StringConcat.concatConstInteger 4711 avgt 15 3.999 ? 0.020 ns/op
+StringConcat.concatConstIntegerString 4711 avgt 15 6.926 ? 0.035 ns/op
+StringConcat.concatConstString 4711 avgt 15 4.975 ? 0.013 ns/op
+StringConcat.concatConstStringConstInt 4711 avgt 15 11.930 ? 1.951 ns/op
+StringConcat.concatEmptyConstInt 4711 avgt 15 5.597 ? 0.024 ns/op
+StringConcat.concatEmptyConstString 4711 avgt 15 2.081 ? 0.024 ns/op
+StringConcat.concatEmptyLeft 4711 avgt 15 2.244 ? 0.025 ns/op
+StringConcat.concatEmptyRight 4711 avgt 15 2.410 ? 0.052 ns/op
+StringConcat.concatMethodConstString 4711 avgt 15 5.041 ? 0.010 ns/op
+StringConcat.concatMix4String 4711 avgt 15 78.331 ? 0.604 ns/op
+StringConcat.concatStringBoolString 4711 avgt 15 19.291 ? 1.504 ns/op
+StringConcat.concatStringBooleanString 4711 avgt 15 9.847 ? 0.105 ns/op
+StringConcat.concatStringIntString 4711 avgt 15 17.951 ? 0.388 ns/op
+StringConcat.concatStringIntegerString 4711 avgt 15 9.237 ? 0.164 ns/op
+StringConcatStartup.MixedLarge.run N/A ss 10 102.619 ? 4.217 ms/op
+StringConcatStartup.MixedSmall.run N/A ss 20 4.819 ? 0.158 ms/op
+StringConcatStartup.StringLarge.run N/A ss 10 42.792 ? 1.655 ms/op
+StringConcatStartup.StringSingle.constBool 4711 ss 40 0.425 ? 0.009 ms/op
+StringConcatStartup.StringSingle.constBoolString 4711 ss 40 0.461 ? 0.012 ms/op
+StringConcatStartup.StringSingle.constBoolean 4711 ss 40 0.133 ? 0.004 ms/op
+StringConcatStartup.StringSingle.constBooleanString 4711 ss 40 0.456 ? 0.016 ms/op
+StringConcatStartup.StringSingle.constFloat 4711 ss 40 0.631 ? 0.017 ms/op
+StringConcatStartup.StringSingle.constFloatString 4711 ss 40 0.920 ? 0.025 ms/op
+StringConcatStartup.StringSingle.constInt 4711 ss 40 0.427 ? 0.021 ms/op
+StringConcatStartup.StringSingle.constIntString 4711 ss 40 0.444 ? 0.015 ms/op
+StringConcatStartup.StringSingle.constInteger 4711 ss 40 0.135 ? 0.004 ms/op
+StringConcatStartup.StringSingle.constIntegerString 4711 ss 40 0.461 ? 0.014 ms/op
+StringConcatStartup.StringSingle.constString 4711 ss 40 0.133 ? 0.008 ms/op
+StringConcatStartup.StringThree.stringIntString 4711 ss 40 1.316 ? 0.041 ms/op
+StringConcatStartup.StringThree.stringIntegerString 4711 ss 40 0.394 ? 0.010 ms/op
| | baseline | current | current2 | delta | delta2 |
| --- | --- | --- | --- | --- | --- |
| StringConcat.concat123String | 990.214 | 980.749 | 973.317 | 0.97% | 1.74% |
| StringConcat.concat13String | 45.810 | 46.520 | 44.808 | -1.53% | 2.24% |
| StringConcat.concat13StringConst | 75.283 | 71.920 | 67.801 | 4.68% | 11.04% |
| StringConcat.concat23String | 90.812 | 93.629 | 93.563 | -3.01% | -2.94% |
| StringConcat.concat23StringConst | 101.114 | 110.605 | 110.992 | -8.58% | -8.90% |
| StringConcat.concat30Mix | 262.114 | 376.001 | 369.601 | -30.29% | -29.08% |
| StringConcat.concat3String | 12.607 | 12.492 | 11.885 | 0.92% | 6.07% |
| StringConcat.concat4String | 13.935 | 13.968 | 13.974 | -0.24% | -0.28% |
| StringConcat.concat6String | 19.831 | 19.758 | 19.828 | 0.37% | 0.02% |
| StringConcat.concatConst2String | 9.491 | 9.479 | 9.505 | 0.13% | -0.15% |
| StringConcat.concatConst4String | 14.786 | 14.800 | 14.818 | -0.09% | -0.22% |
| StringConcat.concatConst6Object | 51.650 | 51.606 | 82.329 | 0.09% | -37.26% |
| StringConcat.concatConst6String | 19.553 | 19.513 | 22.217 | 0.20% | -11.99% |
| StringConcat.concatConstBool | 3.439 | 3.465 | 3.431 | -0.75% | 0.23% |
| StringConcat.concatConstBoolByte | 6.440 | 6.431 | 6.573 | 0.14% | -2.02% |
| StringConcat.concatConstBoolString | 7.054 | 7.030 | 7.016 | 0.34% | 0.54% |
| StringConcat.concatConstBoolean | 3.965 | 3.965 | 3.971 | 0.00% | -0.15% |
| StringConcat.concatConstBooleanString | 7.298 | 7.308 | 7.336 | -0.14% | -0.52% |
| StringConcat.concatConstFloat | 58.590 | 58.247 | 58.261 | 0.59% | 0.56% |
| StringConcat.concatConstFloatString | 59.409 | 60.221 | 59.223 | -1.35% | 0.31% |
| StringConcat.concatConstInt | 6.074 | 6.080 | 6.103 | -0.10% | -0.48% |
| StringConcat.concatConstIntConstInt | 9.726 | 9.800 | 9.839 | -0.76% | -1.15% |
| StringConcat.concatConstIntString | 15.178 | 14.696 | 15.349 | 3.28% | -1.11% |
| StringConcat.concatConstInteger | 4.002 | 4.006 | 3.999 | -0.10% | 0.08% |
| StringConcat.concatConstIntegerString | 7.040 | 6.922 | 6.926 | 1.70% | 1.65% |
| StringConcat.concatConstString | 4.983 | 4.992 | 4.975 | -0.18% | 0.16% |
| StringConcat.concatConstStringConstInt | 11.906 | 11.693 | 11.930 | 1.82% | -0.20% |
| StringConcat.concatEmptyConstInt | 5.618 | 5.628 | 5.597 | -0.18% | 0.38% |
| StringConcat.concatEmptyConstString | 2.058 | 2.065 | 2.081 | -0.34% | -1.11% |
| StringConcat.concatEmptyLeft | 2.216 | 2.231 | 2.244 | -0.67% | -1.25% |
| StringConcat.concatEmptyRight | 2.373 | 2.398 | 2.410 | -1.04% | -1.54% |
| StringConcat.concatMethodConstString | 4.973 | 5.013 | 5.041 | -0.80% | -1.35% |
| StringConcat.concatMix4String | 84.747 | 80.071 | 78.331 | 5.84% | 8.19% |
| StringConcat.concatStringBoolString | 18.836 | 19.235 | 19.291 | -2.07% | -2.36% |
| StringConcat.concatStringBooleanString | 9.878 | 9.780 | 9.847 | 1.00% | 0.31% |
| StringConcat.concatStringIntString | 18.083 | 18.258 | 17.951 | -0.96% | 0.74% |
| StringConcat.concatStringIntegerString | 9.099 | 9.161 | 9.237 | -0.68% | -1.49% |
| StringConcatStartup.MixedLarge.run | 315.546 | 310.811 | 102.619 | 1.52% | 207.49% |
| StringConcatStartup.MixedSmall.run | 24.704 | 24.526 | 4.819 | 0.73% | 412.64% |
| StringConcatStartup.StringLarge.run | 87.007 | 86.733 | 42.792 | 0.32% | 103.33% |
| StringConcatStartup.StringSingle.constBool | 2.102 | 2.139 | 0.425 | -1.73% | 394.59% |
| StringConcatStartup.StringSingle.constBoolString | 0.261 | 0.267 | 0.461 | -2.25% | -43.38% |
| StringConcatStartup.StringSingle.constBoolean | 0.147 | 0.144 | 0.133 | 2.08% | 10.53% |
| StringConcatStartup.StringSingle.constBooleanString | 3.506 | 3.610 | 0.456 | -2.88% | 668.86% |
| StringConcatStartup.StringSingle.constFloat | 2.628 | 2.683 | 0.631 | -2.05% | 316.48% |
| StringConcatStartup.StringSingle.constFloatString | 4.473 | 4.491 | 0.920 | -0.40% | 386.20% |
| StringConcatStartup.StringSingle.constInt | 2.022 | 2.073 | 0.427 | -2.46% | 373.54% |
| StringConcatStartup.StringSingle.constIntString | 0.150 | 0.158 | 0.444 | -5.06% | -66.22% |
| StringConcatStartup.StringSingle.constInteger | 0.144 | 0.146 | 0.135 | -1.37% | 6.67% |
| StringConcatStartup.StringSingle.constIntegerString | 3.541 | 3.640 | 0.461 | -2.72% | 668.11% |
| StringConcatStartup.StringSingle.constString | 0.138 | 0.147 | 0.133 | -6.12% | 3.76% |
| StringConcatStartup.StringThree.stringIntString | 6.166 | 6.189 | 1.316 | -0.37% | 368.54% |
| StringConcatStartup.StringThree.stringIntegerString | 5.123 | 5.250 | 0.394 | -2.42% | 1200.25% |
It can be seen that the following scenarios are performance regressions:
| | baseline | current | current2 | delta | delta2 |
| --- | --- | --- | --- | --- | --- |
| StringConcat.concat23String | 90.812 | 93.629 | 93.563 | -3.01% | -2.94% |
| StringConcat.concat23StringConst | 101.114 | 110.605 | 110.992 | -8.58% | -8.90% |
| StringConcat.concat30Mix | 262.114 | 376.001 | 369.601 | -30.29% | -29.08% |
| StringConcat.concatConst6Object | 51.650 | 51.606 | 82.329 | 0.09% | -37.26% |
| StringConcat.concatConst6String | 19.553 | 19.513 | 22.217 | 0.20% | -11.99% |
| StringConcatStartup.StringSingle.constBoolString | 0.261 | 0.267 | 0.461 | -2.25% | -43.38% |
| StringConcatStartup.StringSingle.constIntString | 0.150 | 0.158 | 0.444 | -5.06% | -66.22% |
-------------
PR Comment: https://git.openjdk.org/jdk/pull/20273#issuecomment-2264217921
More information about the core-libs-dev
mailing list