RFR: 8338532: Speed up the ClassFile API MethodTypeDesc#ofDescriptor [v3]

Shaojin Wen duke at openjdk.org
Tue Aug 20 16:49:00 UTC 2024


On Tue, 20 Aug 2024 12:39:14 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.
>
> Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision:
> 
>   remove specialization for `Ljava/lang/Object;`

After removing the specialization for `Ljava/lang/Object;`, the performance numbers on multiple platforms are as follows.

In scenarios where the number of parameters is greater than 9, the performance is slightly degraded. In most other scenarios, the performance is significantly improved.

## Benchmark Script

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

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


## Benchmark Numbers

### 2.1 MacBook M1 Pro

-# baseline
-Benchmark                                                                            (descString)  Mode  Cnt     Score    Error  Units
-MethodTypeDescFactories.ofDescriptor                      (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    99.955 ?  1.148  ns/op
-MethodTypeDescFactories.ofDescriptor                                                          ()V  avgt    6     3.852 ?  0.046  ns/op
-MethodTypeDescFactories.ofDescriptor     (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6   138.085 ?  1.482  ns/op
-MethodTypeDescFactories.ofDescriptor     (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;  avgt    6   142.119 ? 12.164  ns/op
-MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;  avgt    6   146.175 ? 19.254  ns/op
-MethodTypeDescFactories.ofDescriptor                                         ()Ljava/lang/Object;  avgt    6    23.943 ?  0.104  ns/op
-MethodTypeDescFactories.ofDescriptor                     ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   235.947 ? 55.958  ns/op
-MethodTypeDescFactories.ofDescriptor                                        ()[Ljava/lang/String;  avgt    6    20.620 ?  0.033  ns/op
-MethodTypeDescFactories.ofDescriptor                                                     (..IIJ)V  avgt    6   256.069 ? 52.580  ns/op
-MethodTypeDescFactories.ofDescriptor                                            ([III.Z[B..[.[B).  avgt    6   339.915 ?  2.157  ns/op
-MethodTypeDescFactories.ofDescriptor                                     (.....................).  avgt    6  1116.437 ?  5.817  ns/op

+# current
+Benchmark                                                                            (descString)  Mode  Cnt     Score    Error  Units
+MethodTypeDescFactories.ofDescriptor                      (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    94.979 ? 11.222  ns/op
+MethodTypeDescFactories.ofDescriptor                                                          ()V  avgt    6     1.402 ?  0.012  ns/op
+MethodTypeDescFactories.ofDescriptor     (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6   123.435 ?  6.001  ns/op
+MethodTypeDescFactories.ofDescriptor     (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;  avgt    6   106.590 ?  5.809  ns/op
+MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;  avgt    6   126.491 ? 10.543  ns/op
+MethodTypeDescFactories.ofDescriptor                                         ()Ljava/lang/Object;  avgt    6    20.053 ?  0.154  ns/op
+MethodTypeDescFactories.ofDescriptor                     ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    64.872 ?  1.508  ns/op
+MethodTypeDescFactories.ofDescriptor                                        ()[Ljava/lang/String;  avgt    6    20.943 ?  0.038  ns/op
+MethodTypeDescFactories.ofDescriptor                                                     (..IIJ)V  avgt    6   118.211 ?  1.680  ns/op
+MethodTypeDescFactories.ofDescriptor                                            ([III.Z[B..[.[B).  avgt    6   335.239 ?  2.006  ns/op
+MethodTypeDescFactories.ofDescriptor                                     (.....................).  avgt    6  1151.183 ? 18.441  ns/op


| pattern | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 99.955 | 94.979 | 5.24% |
| ()V | 3.852 | 1.402 | 174.75% |
| (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; | 138.085 | 123.435 | 11.87% |
| (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; | 142.119 | 106.590 | 33.33% |
| (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer; | 146.175 | 126.491 | 15.56% |
| ()Ljava/lang/Object; | 23.943 | 20.053 | 19.40% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 235.947 | 64.872 | 263.71% |
| ()[Ljava/lang/String; | 20.620 | 20.943 | -1.54% |
| (..IIJ)V | 256.069 | 118.211 | 116.62% |
| ([III.Z[B..[.[B). | 339.915 | 335.239 | 1.39% |
| (.....................). | 1116.437 | 1151.183 | -3.02% |

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

# baseline
-Benchmark                                                                            (descString)  Mode  Cnt     Score    Error  Units
-MethodTypeDescFactories.ofDescriptor                      (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    69.519 ±  0.085  ns/op
-MethodTypeDescFactories.ofDescriptor                                                          ()V  avgt    6    10.187 ±  0.027  ns/op
-MethodTypeDescFactories.ofDescriptor     (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6    82.484 ±  0.133  ns/op
-MethodTypeDescFactories.ofDescriptor     (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;  avgt    6    82.436 ±  0.325  ns/op
-MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;  avgt    6    84.290 ±  0.427  ns/op
-MethodTypeDescFactories.ofDescriptor                                         ()Ljava/lang/Object;  avgt    6    20.850 ±  0.067  ns/op
-MethodTypeDescFactories.ofDescriptor                     ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    98.031 ±  0.233  ns/op
-MethodTypeDescFactories.ofDescriptor                                        ()[Ljava/lang/String;  avgt    6    26.571 ±  0.117  ns/op
-MethodTypeDescFactories.ofDescriptor                                                     (..IIJ)V  avgt    6   143.015 ±  0.635  ns/op
-MethodTypeDescFactories.ofDescriptor                                            ([III.Z[B..[.[B).  avgt    6   359.922 ±  1.115  ns/op
-MethodTypeDescFactories.ofDescriptor                                     (.....................).  avgt    6  1138.662 ± 15.073  ns/op

+# current
+Benchmark                                                                            (descString)  Mode  Cnt     Score   Error  Units
+MethodTypeDescFactories.ofDescriptor                      (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    52.467 ± 0.093  ns/op
+MethodTypeDescFactories.ofDescriptor                                                          ()V  avgt    6     1.373 ± 0.005  ns/op
+MethodTypeDescFactories.ofDescriptor     (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6    74.534 ± 0.234  ns/op
+MethodTypeDescFactories.ofDescriptor     (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;  avgt    6    75.800 ± 0.542  ns/op
+MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;  avgt    6    77.573 ± 0.632  ns/op
+MethodTypeDescFactories.ofDescriptor                                         ()Ljava/lang/Object;  avgt    6    20.396 ± 0.058  ns/op
+MethodTypeDescFactories.ofDescriptor                     ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    78.385 ± 1.060  ns/op
+MethodTypeDescFactories.ofDescriptor                                        ()[Ljava/lang/String;  avgt    6    21.528 ± 0.047  ns/op
+MethodTypeDescFactories.ofDescriptor                                                     (..IIJ)V  avgt    6   130.432 ± 0.393  ns/op
+MethodTypeDescFactories.ofDescriptor                                            ([III.Z[B..[.[B).  avgt    6   368.812 ± 0.791  ns/op
+MethodTypeDescFactories.ofDescriptor                                     (.....................).  avgt    6  1165.988 ± 7.120  ns/op


| pattern | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 69.519 | 52.467 | 32.50% |
| ()V | 10.187 | 1.373 | 641.95% |
| (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; | 82.484 | 74.534 | 10.67% |
| (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; | 82.436 | 75.800 | 8.75% |
| (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer; | 84.290 | 77.573 | 8.66% |
| ()Ljava/lang/Object; | 20.850 | 20.396 | 2.23% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 98.031 | 78.385 | 25.06% |
| ()[Ljava/lang/String; | 26.571 | 21.528 | 23.43% |
| (..IIJ)V | 143.015 | 130.432 | 9.65% |
| ([III.Z[B..[.[B). | 359.922 | 368.812 | -2.41% |
| (.....................). | 1138.662 | 1165.988 | -2.34% |

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


-# baseline
-Benchmark                                                                            (descString)  Mode  Cnt     Score   Error  Units
-MethodTypeDescFactories.ofDescriptor                      (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    72.201 ± 0.681  ns/op
-MethodTypeDescFactories.ofDescriptor                                                          ()V  avgt    6    13.187 ± 0.098  ns/op
-MethodTypeDescFactories.ofDescriptor     (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6    85.283 ± 0.842  ns/op
-MethodTypeDescFactories.ofDescriptor     (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;  avgt    6    85.462 ± 0.697  ns/op
-MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;  avgt    6    86.912 ± 0.836  ns/op
-MethodTypeDescFactories.ofDescriptor                                         ()Ljava/lang/Object;  avgt    6    21.551 ± 0.162  ns/op
-MethodTypeDescFactories.ofDescriptor                     ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    90.938 ± 0.299  ns/op
-MethodTypeDescFactories.ofDescriptor                                        ()[Ljava/lang/String;  avgt    6    22.450 ± 0.288  ns/op
-MethodTypeDescFactories.ofDescriptor                                                     (..IIJ)V  avgt    6   152.704 ± 2.675  ns/op
-MethodTypeDescFactories.ofDescriptor                                            ([III.Z[B..[.[B).  avgt    6   385.490 ± 1.188  ns/op
-MethodTypeDescFactories.ofDescriptor                                     (.....................).  avgt    6  1213.829 ± 6.822  ns/op

+# current
+Benchmark                                                                            (descString)  Mode  Cnt     Score    Error  Units
+MethodTypeDescFactories.ofDescriptor                      (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    53.754 ±  0.634  ns/op
+MethodTypeDescFactories.ofDescriptor                                                          ()V  avgt    6     1.576 ±  0.002  ns/op
+MethodTypeDescFactories.ofDescriptor     (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6    74.727 ±  0.364  ns/op
+MethodTypeDescFactories.ofDescriptor     (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;  avgt    6    75.601 ±  0.407  ns/op
+MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;  avgt    6    77.970 ±  0.534  ns/op
+MethodTypeDescFactories.ofDescriptor                                         ()Ljava/lang/Object;  avgt    6    20.358 ±  0.154  ns/op
+MethodTypeDescFactories.ofDescriptor                     ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6    76.490 ±  0.469  ns/op
+MethodTypeDescFactories.ofDescriptor                                        ()[Ljava/lang/String;  avgt    6    21.699 ±  0.089  ns/op
+MethodTypeDescFactories.ofDescriptor                                                     (..IIJ)V  avgt    6   151.431 ±  2.457  ns/op
+MethodTypeDescFactories.ofDescriptor                                            ([III.Z[B..[.[B).  avgt    6   404.335 ±  7.515  ns/op
+MethodTypeDescFactories.ofDescriptor                                     (.....................).  avgt    6  1249.459 ± 14.023  ns/op


| pattern | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 72.201 | 53.754 | 34.32% |
| ()V | 13.187 | 1.576 | 736.74% |
| (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; | 85.283 | 74.727 | 14.13% |
| (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; | 85.462 | 75.601 | 13.04% |
| (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer; | 86.912 | 77.970 | 11.47% |
| ()Ljava/lang/Object; | 21.551 | 20.358 | 5.86% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 90.938 | 76.490 | 18.89% |
| ()[Ljava/lang/String; | 22.450 | 21.699 | 3.46% |
| (..IIJ)V | 152.704 | 151.431 | 0.84% |
| ([III.Z[B..[.[B). | 385.490 | 404.335 | -4.66% |
| (.....................). | 1213.829 | 1249.459 | -2.85% |


###  2.4 Aliyun ECS c8y
* Aliyun Yitian710 CPU (Linxu aarch64)


-# baseline
-Benchmark                                                                            (descString)  Mode  Cnt     Score   Error  Units
-MethodTypeDescFactories.ofDescriptor                      (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    97.690 ± 0.388  ns/op
-MethodTypeDescFactories.ofDescriptor                                                          ()V  avgt    6     5.866 ± 0.046  ns/op
-MethodTypeDescFactories.ofDescriptor     (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6   119.637 ± 0.626  ns/op
-MethodTypeDescFactories.ofDescriptor     (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;  avgt    6   122.579 ± 1.465  ns/op
-MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;  avgt    6   119.111 ± 0.819  ns/op
-MethodTypeDescFactories.ofDescriptor                                         ()Ljava/lang/Object;  avgt    6    37.169 ± 1.096  ns/op
-MethodTypeDescFactories.ofDescriptor                     ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   126.633 ± 2.096  ns/op
-MethodTypeDescFactories.ofDescriptor                                        ()[Ljava/lang/String;  avgt    6    31.170 ± 0.244  ns/op
-MethodTypeDescFactories.ofDescriptor                                                     (..IIJ)V  avgt    6   197.251 ± 3.018  ns/op
-MethodTypeDescFactories.ofDescriptor                                            ([III.Z[B..[.[B).  avgt    6   572.934 ± 2.635  ns/op
-MethodTypeDescFactories.ofDescriptor                                     (.....................).  avgt    6  1751.494 ± 7.532  ns/op

+# current
+Benchmark                                                                            (descString)  Mode  Cnt     Score    Error  Units
+MethodTypeDescFactories.ofDescriptor                      (Ljava/lang/Object;Ljava/lang/String;)I  avgt    6    73.081 ±  1.390  ns/op
+MethodTypeDescFactories.ofDescriptor                                                          ()V  avgt    6     1.729 ±  0.019  ns/op
+MethodTypeDescFactories.ofDescriptor     (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;  avgt    6   104.971 ±  0.846  ns/op
+MethodTypeDescFactories.ofDescriptor     (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;  avgt    6   105.693 ±  0.963  ns/op
+MethodTypeDescFactories.ofDescriptor  (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;  avgt    6   108.848 ±  1.048  ns/op
+MethodTypeDescFactories.ofDescriptor                                         ()Ljava/lang/Object;  avgt    6    30.309 ±  0.181  ns/op
+MethodTypeDescFactories.ofDescriptor                     ([IJLjava/lang/String;Z)Ljava/util/List;  avgt    6   108.834 ±  0.875  ns/op
+MethodTypeDescFactories.ofDescriptor                                        ()[Ljava/lang/String;  avgt    6    30.475 ±  0.531  ns/op
+MethodTypeDescFactories.ofDescriptor                                                     (..IIJ)V  avgt    6   182.938 ±  2.459  ns/op
+MethodTypeDescFactories.ofDescriptor                                            ([III.Z[B..[.[B).  avgt    6   526.788 ±  7.156  ns/op
+MethodTypeDescFactories.ofDescriptor                                     (.....................).  avgt    6  1732.646 ± 10.851  ns/op


| pattern | baseline  | current | delta |
| --- | --- | --- | --- |
| (Ljava/lang/Object;Ljava/lang/String;)I | 97.690 | 73.081 | 33.67% |
| ()V | 5.866 | 1.729 | 239.27% |
| (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; | 119.637 | 104.971 | 13.97% |
| (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; | 122.579 | 105.693 | 15.98% |
| (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer; | 119.111 | 108.848 | 9.43% |
| ()Ljava/lang/Object; | 37.169 | 30.309 | 22.63% |
| ([IJLjava/lang/String;Z)Ljava/util/List; | 126.633 | 108.834 | 16.35% |
| ()[Ljava/lang/String; | 31.170 | 30.475 | 2.28% |
| (..IIJ)V | 197.251 | 182.938 | 7.82% |
| ([III.Z[B..[.[B). | 572.934 | 526.788 | 8.76% |
| (.....................). | 1751.494 | 1732.646 | 1.09% |

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

PR Comment: https://git.openjdk.org/jdk/pull/20611#issuecomment-2299302549


More information about the core-libs-dev mailing list