RFR: 8309413: General improvements to MethodTypeDesc implementation [v5]

Mandy Chung mchung at openjdk.org
Mon Jun 5 18:05:21 UTC 2023


On Sun, 4 Jun 2023 23:52:37 GMT, Chen Liang <liach at openjdk.org> wrote:

>> This patch aims to improve the performance of MethodTypeDesc in general, as it is currently a performance bottleneck in the Classfile API. A previous revision changed the parameter storage from an array to a list; this is dropped now. Sorry for the force push.
>> 
>> 
>> Benchmark                                                             (descString)  Mode  Cnt    Score   Error  Units
>> MethodTypeDescFactories.descriptorString   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6   27.778 ± 0.573  ns/op
>> MethodTypeDescFactories.descriptorString                                       ()V  avgt    6   13.343 ± 0.235  ns/op
>> MethodTypeDescFactories.descriptorString  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   40.828 ± 0.448  ns/op
>> MethodTypeDescFactories.descriptorString                     ()[Ljava/lang/String;  avgt    6   14.754 ± 0.162  ns/op
>> MethodTypeDescFactories.ofArray            (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    8.616 ± 0.132  ns/op
>> MethodTypeDescFactories.ofArray                                                ()V  avgt    6    2.146 ± 0.293  ns/op
>> MethodTypeDescFactories.ofArray           ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   14.595 ± 0.235  ns/op
>> MethodTypeDescFactories.ofArray                              ()[Ljava/lang/String;  avgt    6    2.064 ± 0.085  ns/op
>> MethodTypeDescFactories.ofDescriptor       (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6   97.077 ± 2.482  ns/op
>> MethodTypeDescFactories.ofDescriptor                                           ()V  avgt    6   13.563 ± 0.111  ns/op
>> MethodTypeDescFactories.ofDescriptor      ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6  130.543 ± 2.847  ns/op
>> MethodTypeDescFactories.ofDescriptor                         ()[Ljava/lang/String;  avgt    6   35.286 ± 0.260  ns/op
>> MethodTypeDescFactories.ofList             (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    4.156 ± 0.258  ns/op
>> MethodTypeDescFactories.ofList                                                 ()V  avgt    6    2.192 ± 0.063  ns/op
>> MethodTypeDescFactories.ofList            ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   41.002 ± 0.235  ns/op
>> MethodTypeDescFactories.ofList                               ()[Ljava/lang/String;  avgt    6    2.200 ± 0.041  ns/op
>
> Chen Liang has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains two commits:
> 
>  - Forgot to upload latest micro
>  - general optimizations to MTD, no longer change backing storage

Some comments in `MethodTypeDesc` and its implementation.  Will take a look at the test.

I'd like to see the ClassFile implementation changes in a separate PR that needs @asotona to give input and review.    The proposed change in the ClassFile implementation is trivial but I can't really tell what the performance issue is (of course, I know it avoids the array allocation).

For ClassFile performance issues, it would be useful to have the understanding of the major issues that contribute to the performance overhead.   That would help consider the fixes and alternatives.

src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java line 99:

> 97:      */
> 98:     static MethodTypeDesc of(ClassDesc returnDesc, ClassDesc... paramDescs) {
> 99:         if (paramDescs.length == 0)

`paramDescs` could be null.

src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java line 205:

> 203:      */
> 204:     default String descriptorString() {
> 205:         var sj = new StringJoiner("", "(", ")" + returnType().descriptorString());

`MethodTypeDescImpl` is the only class implementing `MethodTypeDesc` and implements `descriptorString()`.    This default implementation is not needed.   Should the implementation be moved to `MethodTypeDescImpl::descriptorString`?

src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java line 84:

> 82:             paramTypes = new ClassDesc[paramCount];
> 83:             for (int i = 0; i < paramCount; i++) {
> 84:                 paramTypes[i] = validateParameter(ClassDesc.ofDescriptor(types.get(i + 1)));

It seems useful to have a static factory method to take a trusted copy of parameter types and it will validate the parameters before constructing `MethodTypeDescImpl` instance.   Parameter validation in one single place.    Several methods doing the validation can simply call this factory method and the code would be cleaner.

`insertParameterTypes` can call it as well and overhead of re-validating existing parameter types isn't a big issue.

test/jdk/java/lang/constant/MethodTypeDescTest.java line 64:

> 62:         assertEquals(r, MethodTypeDesc.of(r.returnType(), r.parameterList().stream().toArray(ClassDesc[]::new)));
> 63:         assertEquals(r, MethodTypeDesc.of(r.returnType(), IntStream.range(0, r.parameterCount())
> 64:                 .mapToObj(r::parameterType)

this reformatting may be accidental.  Please keep the original format.   Same applies to other reformatted lines in this file.

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

PR Review: https://git.openjdk.org/jdk/pull/13186#pullrequestreview-1463008651
PR Review Comment: https://git.openjdk.org/jdk/pull/13186#discussion_r1218356523
PR Review Comment: https://git.openjdk.org/jdk/pull/13186#discussion_r1218369052
PR Review Comment: https://git.openjdk.org/jdk/pull/13186#discussion_r1218377366
PR Review Comment: https://git.openjdk.org/jdk/pull/13186#discussion_r1218380489


More information about the core-libs-dev mailing list