RFR: 8259065: Optimize MessageDigest.getInstance [v3]
Valerie Peng
valeriep at openjdk.java.net
Thu Jan 7 00:54:00 UTC 2021
On Wed, 6 Jan 2021 01:27:09 GMT, Claes Redestad <redestad at openjdk.org> wrote:
>> By caching default constructors used in `java.security.Provider::newInstanceUtil` in a `ClassValue`, we can reduce the overhead of allocating instances in a variety of places, e.g., `MessageDigest::getInstance`, without compromising thread-safety or security.
>>
>> On the provided microbenchmark `MessageDigest.getInstance(digesterName)` improves substantially for any `digesterName` - around -90ns/op and -120B/op:
>> Benchmark (digesterName) Mode Cnt Score Error Units
>> GetMessageDigest.getInstance md5 avgt 30 293.929 ± 11.294 ns/op
>> GetMessageDigest.getInstance:·gc.alloc.rate.norm md5 avgt 30 424.028 ± 0.003 B/op
>> GetMessageDigest.getInstance SHA-1 avgt 30 322.928 ± 16.503 ns/op
>> GetMessageDigest.getInstance:·gc.alloc.rate.norm SHA-1 avgt 30 688.039 ± 0.003 B/op
>> GetMessageDigest.getInstance SHA-256 avgt 30 338.140 ± 13.902 ns/op
>> GetMessageDigest.getInstance:·gc.alloc.rate.norm SHA-256 avgt 30 640.037 ± 0.002 B/op
>> GetMessageDigest.getInstanceWithProvider md5 avgt 30 312.066 ± 12.805 ns/op
>> GetMessageDigest.getInstanceWithProvider:·gc.alloc.rate.norm md5 avgt 30 424.029 ± 0.003 B/op
>> GetMessageDigest.getInstanceWithProvider SHA-1 avgt 30 345.777 ± 16.669 ns/op
>> GetMessageDigest.getInstanceWithProvider:·gc.alloc.rate.norm SHA-1 avgt 30 688.040 ± 0.003 B/op
>> GetMessageDigest.getInstanceWithProvider SHA-256 avgt 30 371.134 ± 18.485 ns/op
>> GetMessageDigest.getInstanceWithProvider:·gc.alloc.rate.norm SHA-256 avgt 30 640.039 ± 0.004 B/op
>> Patch:
>> Benchmark (digesterName) Mode Cnt Score Error Units
>> GetMessageDigest.getInstance md5 avgt 30 210.629 ± 6.598 ns/op
>> GetMessageDigest.getInstance:·gc.alloc.rate.norm md5 avgt 30 304.021 ± 0.002 B/op
>> GetMessageDigest.getInstance SHA-1 avgt 30 229.161 ± 8.158 ns/op
>> GetMessageDigest.getInstance:·gc.alloc.rate.norm SHA-1 avgt 30 568.030 ± 0.002 B/op
>> GetMessageDigest.getInstance SHA-256 avgt 30 260.013 ± 15.032 ns/op
>> GetMessageDigest.getInstance:·gc.alloc.rate.norm SHA-256 avgt 30 520.030 ± 0.002 B/op
>> GetMessageDigest.getInstanceWithProvider md5 avgt 30 231.928 ± 10.455 ns/op
>> GetMessageDigest.getInstanceWithProvider:·gc.alloc.rate.norm md5 avgt 30 304.020 ± 0.002 B/op
>> GetMessageDigest.getInstanceWithProvider SHA-1 avgt 30 247.178 ± 11.209 ns/op
>> GetMessageDigest.getInstanceWithProvider:·gc.alloc.rate.norm SHA-1 avgt 30 568.029 ± 0.002 B/op
>> GetMessageDigest.getInstanceWithProvider SHA-256 avgt 30 265.625 ± 10.465 ns/op
>> GetMessageDigest.getInstanceWithProvider:·gc.alloc.rate.norm SHA-256 avgt 30 520.030 ± 0.003 B/op
>>
>> See: https://cl4es.github.io/2021/01/04/Investigating-MD5-Overheads.html#reflection-overheads for context.
>
> Claes Redestad has updated the pull request incrementally with one additional commit since the last revision:
>
> Add cloneInstance baseline micro
src/java.base/share/classes/java/security/MessageDigest.java line 185:
> 183: MessageDigest md;
> 184:
> 185: GetInstance.Instance instance = GetInstance.getInstance("MessageDigest",
There is another Security.getImpl call inside getInstance(String algorithm, String provider) method. For consistency sake, we should update it also?
src/java.base/share/classes/java/security/Provider.java line 1072:
> 1070: }
> 1071: public int hashCode() {
> 1072: return type.hashCode() ^ algorithm.hashCode();
Is this change really necessary? It's faster to compute with ^, but does the generated hash values are as distinct as using Objects.hash()?
src/java.base/share/classes/java/security/Provider.java line 1930:
> 1928: Class<?> clazz = null;
> 1929: if (cache instanceof WeakReference<?> ref){
> 1930: clazz = (ref == null) ? null : (Class<?>)ref.get();
ref should not be null if the instanceof check is true?
src/java.base/share/classes/java/security/Provider.java line 1963:
> 1961: Constructor<?> con = null;
> 1962: if (cache instanceof WeakReference<?> ref){
> 1963: con = (ref == null) ? null : (Constructor<?>)ref.get();
ref should not be null if the instanceof check is true?
src/java.base/share/classes/sun/security/jca/ProviderConfig.java line 170:
> 168: }
> 169: // DCL
> 170: synchronized (ProviderConfig.class) {
synchronized (this) instead since 'provider' is an instance field?
-------------
PR: https://git.openjdk.java.net/jdk/pull/1933
More information about the security-dev
mailing list