RFR: 8338532: Speed up the ClassFile API MethodTypeDesc#ofDescriptor

Shaojin Wen duke at openjdk.org
Mon Aug 19 06:32:23 UTC 2024


On Fri, 16 Aug 2024 08:53:38 GMT, Shaojin Wen <duke at openjdk.org> wrote:

> The current implementation of ofDescriptor puts return type and parameter types together in an ArrayList, and then splits them into return type and array of parameter types. This ArrayList creation is unnecessary, considering most descriptors only have few parameter types.
> 
> By splitting return type and parameter types separately and scanning the descriptor first to get the number of parameters, we can just allocate an exact, trusted array for the resulting MethodTypeDesc without copy.

Below are the performance numbers running on a MacBook M1 Pro. 
1. In the scenario without parameters, the performance is regressed. 
2. When the number of parameters is >=1 and <=8, the performance is significantly improved. 
3. When the number of parameters is >8, the performance is regressed.

## Benchmark script

# baseline
git checkout 74066bcca82749722e6fee57469520d418bf3430
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"

# current
git checkout a2f88806e04eb08d9d4d64bfa7411fc72dd28497
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"


## Performance numbers

# baseline
Benchmark                                                         (descString)  Mode  Cnt     Score    Error  Units
MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6   102.502 ?  3.680  ns/op
MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     3.840 ?  0.010  ns/op
MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   232.782 ? 60.823  ns/op
MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    25.170 ?  0.036  ns/op
MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   281.701 ? 61.816  ns/op
MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1117.963 ?  8.493  ns/op

# current
Benchmark                                                         (descString)  Mode  Cnt     Score    Error  Units
MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    53.423 ?  1.182  ns/op
MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     4.801 ?  0.065  ns/op
MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    68.220 ?  0.107  ns/op
MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    26.471 ?  0.165  ns/op
MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   123.778 ?  0.542  ns/op
MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1713.325 ? 13.985  ns/op


| descString | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 102.502 | 53.423 | 91.87% |
| ()V | 3.840 | 4.801 | -20.02% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 232.782 | 68.220 | 241.22% |
| ()[Ljava/lang/String; | 25.170 | 26.471 | -4.91% |
| (..IIJ)V | 281.701 | 123.778 | 127.59% |
| (.....................). | 1117.963 | 1713.325 | -34.75% |

The performance regression problem in the scenario without parameters has been solved. It was caused by an extra lastIndexOf.

Below are the performance numbers running on a MacBook M1 Pro.

## Benchmark script

# baseline
git checkout 74066bcca82749722e6fee57469520d418bf3430
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"

# current
git checkout 8b262b2e4e146c72b7c331a89ac201b41893a8b3
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"


## Performance numbers


-# baseline
-Benchmark                                                         (descString)  Mode  Cnt     Score     Error  Units
-MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6   104.154 ?   2.636  ns/op
-MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     3.843 ?   0.014  ns/op
-MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   221.013 ?  81.200  ns/op
-MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    20.603 ?   0.026  ns/op
-MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   221.404 ? 189.754  ns/op
-MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1128.418 ?  16.850  ns/op

+# current
+Benchmark                                                         (descString)  Mode  Cnt     Score   Error  Units
+MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    53.000 ? 0.758  ns/op
+MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     3.548 ? 0.007  ns/op
+MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    68.731 ? 0.084  ns/op
+MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    20.365 ? 0.173  ns/op
+MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   128.002 ? 0.819  ns/op
+MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1663.985 ? 4.529  ns/op


| descString | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 104.154 | 53.000 | 96.52% |
| ()V | 3.843 | 3.548 | 8.31% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 221.013 | 68.731 | 221.56% |
| ()[Ljava/lang/String; | 20.603 | 20.365 | 1.17% |
| (..IIJ)V | 221.404 | 128.002 | 72.97% |
| (.....................). | 1128.418 | 1663.985 | -32.19% |

The following are the performance numbers on multiple platforms. When the number of parameters is > 8, the performance will regress by about 33%. When the number of parameters is <= 8, the performance will be significantly improved or neutral.

## 1. Benchmark script

# baseline
git checkout 74066bcca82749722e6fee57469520d418bf3430
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"

# current
git checkout c02d2306935d99685e34ef960aa72e10feb82a39
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"


## 2. Performance numbers

### 2.1 Mac Book M1 Pro

-# baseline
-Benchmark                                                         (descString)  Mode  Cnt     Score     Error  Units
-MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6   104.154 ?   2.636  ns/op
-MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     3.843 ?   0.014  ns/op
-MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   221.013 ?  81.200  ns/op
-MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    20.603 ?   0.026  ns/op
-MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   221.404 ? 189.754  ns/op
-MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1128.418 ?  16.850  ns/op

+# current
+Benchmark                                                         (descString)  Mode  Cnt     Score    Error  Units
+MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    53.900 ?  0.061  ns/op
+MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     3.609 ?  0.017  ns/op
+MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    69.666 ?  0.596  ns/op
+MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    20.978 ?  0.197  ns/op
+MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   126.968 ?  0.715  ns/op
+MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1651.624 ? 30.462  ns/op


| descString | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 104.154 | 53.900 | 93.24% |
| ()V | 3.843 | 3.609 | 6.48% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 221.013 | 69.666 | 217.25% |
| ()[Ljava/lang/String; | 20.603 | 20.978 | -1.79% |
| (..IIJ)V | 221.404 | 126.968 | 74.38% |
| (.....................). | 1128.418 | 1651.624 | -31.68% |


### 2.2 Aliyun ECS c8a
* AMD CPU (x64)
* Linux


-# baseline
-Benchmark                                                         (descString)  Mode  Cnt     Score    Error  Units
-MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    69.575 ±  0.197  ns/op
-MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6    10.170 ±  0.065  ns/op
-MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    91.331 ±  0.339  ns/op
-MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    22.479 ±  0.108  ns/op
-MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   143.278 ±  0.314  ns/op
-MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1155.946 ± 26.590  ns/op

+# current
+Benchmark                                                         (descString)  Mode  Cnt     Score   Error  Units
+MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    58.870 ± 1.330  ns/op
+MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     3.785 ± 0.039  ns/op
+MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    77.584 ± 0.120  ns/op
+MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    22.040 ± 0.060  ns/op
+MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   139.849 ± 0.397  ns/op
+MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1750.701 ± 3.811  ns/op


| descString | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 69.575 | 58.870 | 18.18% |
| ()V | 10.170 | 3.785 | 168.69% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 91.331 | 77.584 | 17.72% |
| ()[Ljava/lang/String; | 22.479 | 22.040 | 1.99% |
| (..IIJ)V | 143.278 | 139.849 | 2.45% |
| (.....................). | 1155.946 | 1750.701 | -33.97% |


### 2.3 Aliyun ECS c8i
* Intel CPU (x64)
* Linux


-# baseline
-Benchmark                                                         (descString)  Mode  Cnt     Score   Error  Units
-MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    71.377 ± 0.531  ns/op
-MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6    13.137 ± 0.039  ns/op
-MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    90.090 ± 0.303  ns/op
-MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    22.589 ± 0.127  ns/op
-MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   149.114 ± 0.407  ns/op
-MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1213.178 ± 6.771  ns/op

+# current
+Benchmark                                                         (descString)  Mode  Cnt     Score   Error  Units
+MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    57.653 ± 0.874  ns/op
+MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     4.295 ± 0.028  ns/op
+MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    73.995 ± 0.268  ns/op
+MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    22.839 ± 0.148  ns/op
+MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   152.082 ± 0.657  ns/op
+MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1944.548 ± 8.628  ns/op


| descString | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 71.377 | 57.653 | 23.80% |
| ()V | 13.137 | 4.295 | 205.87% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 90.090 | 73.995 | 21.75% |
| ()[Ljava/lang/String; | 22.589 | 22.839 | -1.09% |
| (..IIJ)V | 149.114 | 152.082 | -1.95% |
| (.....................). | 1213.178 | 1944.548 | -37.61% |

### 2.4 Aliyun ECS c8y
* CPU Aliyun Yitian 710 (aarch64)
* Linux


-# baseline
-Benchmark                                                         (descString)  Mode  Cnt     Score    Error  Units
-MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    87.788 ±  1.286  ns/op
-MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     5.894 ±  0.121  ns/op
-MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   130.803 ±  5.688  ns/op
-MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    32.126 ±  0.292  ns/op
-MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   195.543 ±  1.942  ns/op
-MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1600.544 ± 16.898  ns/op

+# current
+Benchmark                                                         (descString)  Mode  Cnt     Score    Error  Units
+MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    82.522 ±  2.328  ns/op
+MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     5.560 ±  0.224  ns/op
+MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   101.175 ±  1.996  ns/op
+MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    31.696 ±  0.736  ns/op
+MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   194.115 ±  1.705  ns/op
+MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  2592.137 ± 22.466  ns/op


| descString | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 69.575 | 58.870 | 18.18% |
| ()V | 10.170 | 3.785 | 168.69% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 91.331 | 77.584 | 17.72% |
| ()[Ljava/lang/String; | 22.479 | 22.040 | 1.99% |
| (..IIJ)V | 143.278 | 139.849 | 2.45% |
| (.....................). | 1155.946 | 1750.701 | -33.97% |

We construct an image with statistical information as follows:


package jdk.internal.constant;

class MethodTypeDescImpl {
    static int invokeCount = 0;
    static int[] stats = new int[40];

    static MethodTypeDescImpl ofDescriptor(String descriptor) {
        // ...

        invokeCount++;
        stats[paramTypes.length]++;

        return result;
    }
}


Build a test to print statistics


public class MethodTypDescStats {
    public static void main(String[] args) throws Exception {
        var cl = Class.forName("jdk.internal.constant.MethodTypeDescImpl");

        Field statsField = cl.getDeclaredField("stats");
        statsField.setAccessible(true);

        Field invokeCountField = cl.getDeclaredField("invokeCount");
        invokeCountField.setAccessible(true);

        int invokeCount = (Integer) invokeCountField.get(null);
        int[] stats = (int[]) statsField.get(null);
        System.out.println("invokeCount : " + invokeCount);
        System.out.println(Arrays.toString(stats));
    }
}


Running Tests

java --add-opens java.base/jdk.internal.constant=ALL-UNNAMED MethodTypDescStats


Output

invokeCount : 110
[93, 24, 32, 37, 11, 7, 5, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]


It can be seen that during the JVM startup process, the MethodTypeDescImpl#ofDescriptor method was executed 110 times, and the number of parameters was greater than 8 twice (both were 9).

According to this data, the optimization of the current version is getting better. It improves significantly when the number of parameters is less than or equal to 8, and decreases slightly when the number of parameters is greater than 8.

Here is where bootstrap uses MethodTypeDesc.ofDescriptor:

at java.base/java.lang.constant.MethodTypeDesc.ofDescriptor(MethodTypeDesc.java:60)
at java.base/jdk.internal.classfile.impl.DirectMethodBuilder.methodTypeSymbol(DirectMethodBuilder.java:88)

Here are the descriptor statistics of bootstrap calling ofDescriptor, `()V` 99 times, accounting for 62.65% of the total, so `()V` should be optimized separately.


invokeCount : 158

99	()V
14	(Ljava/lang/Object;)Ljava/lang/Object;
13	(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
8	()Ljava/lang/Object;
6	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
6	(Ljava/lang/Object;Ljava/lang/Object;)V
5	(Ljava/lang/Object;)Z
4	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;)Ljava/lang/invoke/BoundMethodHandle;
4	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;J)Ljava/lang/invoke/BoundMethodHandle;
4	()Ljava/lang/invoke/BoundMethodHandle$SpeciesData;
4	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
4	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;I)Ljava/lang/invoke/BoundMethodHandle;
4	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;D)Ljava/lang/invoke/BoundMethodHandle;
4	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;F)Ljava/lang/invoke/BoundMethodHandle;
4	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;)Ljava/lang/invoke/BoundMethodHandle;
3	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
3	(Ljava/lang/Object;Ljava/lang/Object;J)Ljava/lang/Object;
3	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
3	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
3	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
3	(Ljava/lang/Object;Ljava/lang/Object;)I
2	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
2	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
2	(Ljava/lang/Object;JLjava/lang/Object;ILjava/lang/Object;)J
2	(Ljava/lang/Object;Ljava/lang/Object;JI)Ljava/lang/Object;
2	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I
2	(Ljava/lang/Object;JI)J
2	(Ljava/lang/module/ModuleFinder;)V
1	(Ljava/lang/Object;I)J
1	(Ljava/lang/Object;I)I
1	(Ljdk/internal/module/SystemModuleFinders$1;Ljava/lang/String;)V
1	(Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;
1	(Ljava/lang/Object;I)V
1	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;J)Ljava/lang/Object;
1	(Ljava/lang/Object;JLjava/lang/Object;I)J
1	(Ljava/lang/Object;J)Ljava/lang/Object;
1	(Ljava/nio/file/Path;)V
1	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;J)Ljava/lang/invoke/BoundMethodHandle;
1	(Ljava/lang/Object;Ljava/lang/Object;JLjava/lang/Object;ILjava/lang/Object;)J
1	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/invoke/BoundMethodHandle;
1	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
1	(Ljava/lang/Object;)I
1	(Ljava/lang/Object;I)Ljava/lang/Object;
1	(Ljava/lang/Object;JI)Ljava/lang/Object;
1	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/invoke/BoundMethodHandle;
1	(Ljava/util/function/BiFunction;)V
1	(Ljava/lang/Object;)V
1	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;J)V
1	(Ljava/io/FileDescriptor;)V
1	(I)Z
1	(Ljava/lang/Object;Ljava/lang/Object;JLjava/lang/Object;I)J
1	(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;J)Ljava/lang/Object;
1	(Ljava/lang/Object;Ljava/lang/Object;)J
1	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;Ljava/lang/Object;)V
1	(Ljdk/internal/module/ModulePath;Ljava/nio/file/Path;)V
1	(Ljava/lang/module/ModuleDescriptor$Builder;)V
1	(Ljava/lang/Object;Ljava/lang/Object;I)J
1	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/invoke/BoundMethodHandle;
1	(ILjava/lang/Object;)Ljava/lang/Object;
1	(Ljava/lang/Object;Ljava/lang/Object;JI)J
1	(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V

Now, the performance of the most frequently called scenario `()V` has been significantly improved.

## 1. Benchmark script


# baseline
git checkout 1e17a42eda73bc5138e05502a004a8c293a93eb8
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"

# baseline
git checkout fa0895650e644602418dcadd9b57d58d1d5fb960
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"


## 2. Performance numbers

### 2.1 Mac Book M1 Pro


-# baseline
-Benchmark                                                         (descString)  Mode  Cnt     Score    Error  Units
-MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6   102.574 ?  4.515  ns/op
-MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     3.744 ?  0.007  ns/op
-MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   227.739 ? 53.035  ns/op
-MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    20.586 ?  0.054  ns/op
-MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   251.047 ? 37.685  ns/op
-MethodTypeDescFactories.ofDescriptor                         ([III.Z[B..[.[B).  avgt    6   340.045 ?  1.722  ns/op
-MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1187.174 ?  5.716  ns/op

+# current
+Benchmark                                                         (descString)  Mode  Cnt     Score    Error  Units
+MethodTypeDescFactories.ofDescriptor   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    64.896 ?  2.925  ns/op
+MethodTypeDescFactories.ofDescriptor                                       ()V  avgt    6     1.397 ?  0.004  ns/op
+MethodTypeDescFactories.ofDescriptor  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    63.757 ?  0.962  ns/op
+MethodTypeDescFactories.ofDescriptor                     ()[Ljava/lang/String;  avgt    6    21.169 ?  0.335  ns/op
+MethodTypeDescFactories.ofDescriptor                                  (..IIJ)V  avgt    6   118.475 ?  0.806  ns/op
+MethodTypeDescFactories.ofDescriptor                         ([III.Z[B..[.[B).  avgt    6   349.402 ? 13.053  ns/op
+MethodTypeDescFactories.ofDescriptor                  (.....................).  avgt    6  1147.295 ?  6.988  ns/op



| pattern | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 102.574 | 64.896 | 58.06% |
| ()V | 3.744 | 1.397 | 168.00% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 227.739 | 63.757 | 257.20% |
| ()[Ljava/lang/String; | 20.586 | 21.169 | -2.75% |
| (..IIJ)V | 251.047 | 118.475 | 111.90% |
| ([III.Z[B..[.[B). | 340.045 | 349.402 | -2.68% |
| (.....................). | 1187.174 | 1147.295 | 3.48% |

I added two startup process descStrings to the benchmark, and now optimized the parameter type of `Ljava/lang/Object` as follows:

## 1. Benchmark script

git remote add wenshao git at github.com:wenshao/jdk.git
git fetch wenshao

# baseline
git checkout b83e2705662aa444338586713a2a7b2fa7852ba6
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"

# current
git checkout 2405e63af284d4074056be40c550918541eead3a
make test TEST="micro:java.lang.constant.MethodTypeDescFactories.ofDescriptor"


## 2. Performance numbers

### 2.1 Mac Book M1 Pro


-# baseline
-Benchmark                                                                         (descString)  Mode  Cnt     Score     Error  Units
-MethodTypeDescFactories.ofDescriptor                   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6   100.245 ?   3.888  ns/op
-MethodTypeDescFactories.ofDescriptor                                                       ()V  avgt    6     3.762 ?   0.024  ns/op
-MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6   148.798 ?  21.645  ns/op
-MethodTypeDescFactories.ofDescriptor                                      ()Ljava/lang/Object;  avgt    6    23.890 ?   0.053  ns/op
-MethodTypeDescFactories.ofDescriptor                  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   220.012 ?  63.268  ns/op
-MethodTypeDescFactories.ofDescriptor                                     ()[Ljava/lang/String;  avgt    6    20.612 ?   0.031  ns/op
-MethodTypeDescFactories.ofDescriptor                                                  (..IIJ)V  avgt    6   167.894 ? 153.553  ns/op
-MethodTypeDescFactories.ofDescriptor                                         ([III.Z[B..[.[B).  avgt    6   342.610 ?   2.296  ns/op
-MethodTypeDescFactories.ofDescriptor                                  (.....................).  avgt    6  1115.834 ?   1.067  ns/op

+# current
+Benchmark                                                                         (descString)  Mode  Cnt     Score   Error  Units
+MethodTypeDescFactories.ofDescriptor                   (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    48.616 ? 0.440  ns/op
+MethodTypeDescFactories.ofDescriptor                                                       ()V  avgt    6     1.400 ? 0.004  ns/op
+MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6    56.567 ? 0.101  ns/op
+MethodTypeDescFactories.ofDescriptor                                      ()Ljava/lang/Object;  avgt    6    16.017 ? 0.036  ns/op
+MethodTypeDescFactories.ofDescriptor                  ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    71.447 ? 0.392  ns/op
+MethodTypeDescFactories.ofDescriptor                                     ()[Ljava/lang/String;  avgt    6    20.948 ? 0.045  ns/op
+MethodTypeDescFactories.ofDescriptor                                                  (..IIJ)V  avgt    6   119.517 ? 0.606  ns/op
+MethodTypeDescFactories.ofDescriptor                                         ([III.Z[B..[.[B).  avgt    6   353.724 ? 7.413  ns/op
+MethodTypeDescFactories.ofDescriptor                                  (.....................).  avgt    6  1161.422 ? 3.517  ns/op


| pattern | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 100.245 | 48.616 | 106.20% |
| ()V | 3.762 | 1.400 | 168.71% |
| (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; | 148.798 | 56.567 | 163.05% |
| ()Ljava/lang/Object; | 23.890 | 16.017 | 49.15% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 220.012 | 71.447 | 207.94% |
| ()[Ljava/lang/String; | 20.612 | 20.948 | -1.60% |
| (..IIJ)V | 167.894 | 119.517 | 40.48% |
| ([III.Z[B..[.[B). | 342.610 | 353.724 | -3.14% |
| (.....................). | 1115.834 | 1161.422 | -3.93% |

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

PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2294501141
PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2294534798
PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2294905823
PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2295132102
PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2295300033
PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2295302133
PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2295328895
PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2295436632


More information about the core-libs-dev mailing list