On Tue, 26 Apr 2022 15:30:41 GMT, Jorn Vernee <jver...@openjdk.org> wrote:

>> The `MethodType.genericMethodType` methods provide convenience methods for 
>> certain common method types and also provide `@Stable` cache that allows for 
>> constant folding. This patch enhances the more generic `methodType` methods 
>> to take advantage of this cache, when possible. This allows calls like 
>> `MethodType.methodType(Object.class, Object.class, ...)` to constant fold, 
>> making them 50x+ faster and allocation-free.
>> 
>> Baseline:
>> 
>> Benchmark                                    Mode  Cnt   Score   Error  Units
>> MethodTypeAcquire.baselineRaw                avgt   15   0.673 ? 0.017  ns/op
>> MethodTypeAcquire.testGenericObject          avgt   15   0.579 ? 0.125  ns/op
>> MethodTypeAcquire.testMultiPType             avgt   15  46.671 ? 1.134  ns/op
>> MethodTypeAcquire.testMultiPType_Arg         avgt   15  27.019 ? 0.437  ns/op
>> MethodTypeAcquire.testMultiPType_ObjectAndA  avgt   15  57.217 ? 0.505  ns/op
>> MethodTypeAcquire.testMultiPType_ObjectOnly  avgt   15  57.114 ? 1.214  ns/op
>> MethodTypeAcquire.testObjectObject           avgt   15  33.380 ? 1.810  ns/op
>> MethodTypeAcquire.testReturnInt              avgt   15  28.043 ? 0.187  ns/op
>> MethodTypeAcquire.testReturnObject           avgt   15  24.313 ? 0.074  ns/op
>> MethodTypeAcquire.testReturnVoid             avgt   15  24.360 ? 0.155  ns/op
>> MethodTypeAcquire.testSinglePType            avgt   15  33.572 ? 1.101  ns/op
>> 
>> 
>> Patched:
>> 
>> Benchmark                                    Mode  Cnt   Score   Error  Units
>> MethodTypeAcquire.baselineRaw                avgt   15   0.683 ? 0.024  ns/op
>> MethodTypeAcquire.testGenericObject          avgt   15   0.547 ? 0.047  ns/op
>> MethodTypeAcquire.testMultiPType             avgt   15  48.532 ? 0.982  ns/op
>> MethodTypeAcquire.testMultiPType_Arg         avgt   15  31.390 ? 5.269  ns/op
>> MethodTypeAcquire.testMultiPType_ObjectAndA  avgt   15  60.165 ? 2.756  ns/op
>> MethodTypeAcquire.testMultiPType_ObjectOnly  avgt   15   0.599 ? 0.166  ns/op
>> MethodTypeAcquire.testObjectObject           avgt   15   0.541 ? 0.045  ns/op
>> MethodTypeAcquire.testReturnInt              avgt   15  28.174 ? 0.257  ns/op
>> MethodTypeAcquire.testReturnObject           avgt   15   0.542 ? 0.045  ns/op
>> MethodTypeAcquire.testReturnVoid             avgt   15  24.621 ? 0.202  ns/op
>> MethodTypeAcquire.testSinglePType            avgt   15  33.614 ? 1.109  ns/op
>> 
>> 
>> The cost on method types that don't match are in the noise (0-2ns/op). Even 
>> on a test I constructed to act as a worst case (`testMultiPType_ObjectAndA`) 
>> there's barely any appreciable cost (~3ns/op, with overlapping error).
>
> test/micro/org/openjdk/bench/java/lang/invoke/MethodTypeAcquire.java line 104:
> 
>> 102:     @Benchmark
>> 103:     public MethodType testMultiPType_ObjectOnly() {
>> 104:         return MethodType.methodType(Object.class, Object.class, 
>> Object.class, Object.class, Object.class, Object.class, Object.class);
> 
> It might be interesting to add a benchmark where all types are `Object`, but 
> non-constants, to see if that case improves as well.

Right.. I did a quick experiment and there's a large speed-up in the trivial 
`methodType(obj, obj)` case:

Benchmark                                      Mode  Cnt   Score   Error  Units
MethodTypeAcquire.testObjectObjectNonConstant  avgt    5  30.052 ? 3.440  ns/op 
# baseline
MethodTypeAcquire.testObjectObjectNonConstant  avgt    5  1.171  ? 0.001  ns/op 
# patch


I'll add a non-constant variant for the multi-arg Object variants, too. It 
should scale linearly and see a gain in the same ballpark. I think we need to 
keep the number of microbenchmarks here somewhat under control, though.

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

PR: https://git.openjdk.java.net/jdk/pull/8398

Reply via email to