RFR: 8285633: Take better advantage of generic MethodType cache
Claes Redestad
redestad at openjdk.java.net
Tue Apr 26 17:24:53 UTC 2022
On Tue, 26 Apr 2022 15:30:41 GMT, Jorn Vernee <jvernee at 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
More information about the core-libs-dev
mailing list