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