RFR: 8259065: Optimize MessageDigest.getInstance
David Schlosnagle
github.com+54594+schlosna at openjdk.java.net
Wed Jan 6 02:33:53 UTC 2021
On Wed, 6 Jan 2021 01:20:40 GMT, Claes Redestad <redestad at openjdk.org> wrote:
>> I refactored and optimized the lookup code further, getting rid of a number of bottlenecks:
>>
>> - Cache Constructors in Provider.Service instead of via a ClassValue.
>> - Also cache the impl Class, wrap Class and Constructor in WeakReference if not loaded by the null classloader (many builtins will be)
>> - Cache EngineDescription in Service, avoiding a lookup on the hot path
>> - We were hitting a synchronized method in ProviderConfig.getProvider(). The provider field is volatile already, so I used the double-check idiom here to avoid synchronization on the hot path
>> - ServiceKey.hashCode using Objects.hash was cause for allocation, simplified and optimized it.
>>
>> Benchmark (digesterName) Mode Cnt Score Error Units
>> GetMessageDigest.getInstance MD5 avgt 30 143.803 ± 5.431 ns/op
>> GetMessageDigest.getInstance:·gc.alloc.rate.norm MD5 avgt 30 280.015 ± 0.001 B/op
>
> Since much of the cost is now the creation of the MessageDigest itself, I added a microbenchmark to stat this overhead:
>
> Benchmark (digesterName) Mode Cnt Score Error Units
> GetMessageDigest.cloneInstance MD5 avgt 30 124.922 ± 5.412 ns/op
> GetMessageDigest.cloneInstance:·gc.alloc.rate.norm MD5 avgt 30 280.015 ± 0.001 B/op
>
> That means there's no added allocation overhead of calling `MessageDigest.getInstance(digesterName)` compared to cloning an existing instance - which means we get almost all of the benefits without resorting to tricks as caching and cloning an instance at call sites such as the one in `UUID::nameUUIDFromBytes`. The remaining 20ns/op difference should be negligible.
Nice speedup for all `MessageDigest.getInstance` and `Provider.getService` invocations and improves on removing the scalability bottlenecks of `Provider.getService` beyond [JDK-7092821](https://bugs.openjdk.java.net/browse/JDK-7092821) (and related [JDK-8080273](https://bugs.openjdk.java.net/browse/JDK-8080273) & [JDK-8172827](https://bugs.openjdk.java.net/browse/JDK-8172827)). This will also allow removing some longstanding `MessageDigest#clone` workarounds such as in Guava https://github.com/google/guava/issues/1197 .
-------------
PR: https://git.openjdk.java.net/jdk/pull/1933
More information about the security-dev
mailing list