RFR: 8291966: SwitchBootstrap.typeSwitch could be faster [v2]

Jan Lahoda jlahoda at openjdk.org
Mon May 29 07:28:06 UTC 2023


On Tue, 17 Jan 2023 15:55:40 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:

>> The pattern matching switches are using a bootstrap method `SwitchBootstrap.typeSwitch` to implement the jumps in the switch. Basically, for a switch like:
>> 
>> switch (obj) {
>>     case String s when s.isEmpty() -> {}
>>     case String s -> {}
>>     case CharSequence cs -> {}
>>     ...
>> }
>> 
>> 
>> this method will produce a MethodHandle that will be analyze the provided selector value (`obj` in the example), and will return the case index to which the switch should jump. This method also accepts a (re)start index for the search, which is used to handle guards. For example, if the `s.isEmpty()` guard in the above sample returns false, the matching is restarted on the next case.
>> 
>> The current implementation is fairly slow, it basically goes through the labels in a loop. The proposal here is to replace that with a MethodHandle structure like this:
>> 
>> obj == null ? -1
>>                   : switch (restartIndex) {
>>                         case 0 -> obj instanceof String ? 0 : obj instanceof CharSequence ? 2 : ... ;
>>                         case 1 -> obj instanceof String ? 1 : obj instanceof CharSequence ? 2 : ... ;
>>                         case 2 -> obj instanceof CharSequence ? 2 : ... ;
>>                         ...
>>                         default -> <labels-count>;
>>                     }
>> 
>> 
>> This appear to run faster than the current implementation, using testcase similar to the one used for https://github.com/openjdk/jdk/pull/9746 , these are the results
>> 
>> PatternsOptimizationTest.testLegacyIndyLongSwitch   thrpt   25   1515989.562 ± 32047.918  ops/s
>> PatternsOptimizationTest.testHandleIndyLongSwitch   thrpt   25   2630707.585 ± 37202.210  ops/s
>> 
>> PatternsOptimizationTest.testLegacyIndyShortSwitch  thrpt   25   6789310.900 ± 61921.636  ops/s
>> PatternsOptimizationTest.testHandleIndyShortSwitch  thrpt   25  10771729.464 ± 69607.467  ops/s
>> 
>> 
>> The "LegacyIndy" is the current implementation, "HandleIndy" is the one proposed here. The translation in javac used is the one from #9746 in all cases.
>
> Jan Lahoda has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision:
> 
>  - Adding comments
>  - Improving performance
>  - Merge branch 'master' into JDK-8291966
>  - 8291966: SwitchBootstrap.typeSwitch could be faster

I've merged with the current master, and tried to reflect the review feedback. I tried to run a performance test:
[PatternsOptimizationTest.java.txt](https://github.com/openjdk/jdk/files/11589470/PatternsOptimizationTest.java.txt)

with these changes (the test uses a patch javac, and an current (old) version of `SwitchBootstraps` - javac use the old bootstrap for classes that contain `Legacy` in their name, new bootstrap in all other cases). The results when I ran this were:

PatternsOptimizationTest.testHandleIndyLongSwitch   thrpt   25  2555536.273 ±   49471.586  ops/s
PatternsOptimizationTest.testLegacyIndyLongSwitch   thrpt   25  1341944.936 ±  163396.221  ops/s

PatternsOptimizationTest.testHandleIndyShortSwitch  thrpt   25  9746865.005 ±  115379.432  ops/s
PatternsOptimizationTest.testLegacyIndyShortSwitch  thrpt   25  5535534.370 ± 1275754.361  ops/s


So, this patch still seems to improve the state.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/9779#issuecomment-1566682417


More information about the core-libs-dev mailing list