corretto / amazon-corretto-crypto-provider

The Amazon Corretto Crypto Provider is a collection of high-performance cryptographic implementations exposed via standard JCA/JCE interfaces.
Apache License 2.0
238 stars 56 forks source link

Avoid unnecessary array copy in singlePass #407

Open pengxiaolong opened 1 month ago

pengxiaolong commented 1 month ago

In allocation profiler result of an internal service, ACCP MD5 digest contributes over 6%, w/ further digging into ACCP implementation, we found the array copy in singlePass could be avoided and it will help with reducing heap pressure and slightly improve the performance of MD5 and other hash implementations from ACCP.

We have tested the fix with JMH:

    private static ThreadLocal<MessageDigest> messageDigest = new ThreadLocal<MessageDigest>() {
        protected synchronized MessageDigest initialValue() {
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("md5");
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException("cannot find md5 algorithm", e);
            }
            return md;
        }
    };

    public static byte[][] inputs = new byte[][]{
            "1234567890123456789012345678901212345678901234567890123456789012".getBytes(), // 64 bytes
            "12345678901234567890123456789012".getBytes(),
            "12345678901234567890123456789012".getBytes(),
            "12345678901234567890123456789012".getBytes(),
            "12345678901234567890123456789012".getBytes(),
            "12345678901234567890123456789012".getBytes(),
            "12345678901234567890123456789012".getBytes(),
            "12345678901234567890123456789012".getBytes()
    };

    @Benchmark
    public static void test() {
        MessageDigest md = messageDigest.get();
        for(byte[] input : inputs) {
            md.digest(input);
        }
    }

JMH result: W/o fix:

Benchmark                                  Mode  Cnt     Score    Error   Units
ACCPMD5Benchmark.test                      avgt    5  1630.452 ± 97.567   ns/op
ACCPMD5Benchmark.test:·gc.alloc.rate       avgt    5   346.316 ± 20.570  MB/sec
ACCPMD5Benchmark.test:·gc.alloc.rate.norm  avgt    5   592.000 ±  0.001    B/op
ACCPMD5Benchmark.test:·gc.count            avgt    5    11.000           counts
ACCPMD5Benchmark.test:·gc.time             avgt    5    11.000               ms

W/ fix:

Benchmark                                  Mode  Cnt     Score    Error   Units
ACCPMD5Benchmark.test                      avgt    5  1583.675 ± 94.346   ns/op
ACCPMD5Benchmark.test:·gc.alloc.rate       avgt    5   154.179 ±  9.225  MB/sec
ACCPMD5Benchmark.test:·gc.alloc.rate.norm  avgt    5   256.000 ±  0.001    B/op
ACCPMD5Benchmark.test:·gc.count            avgt    5     4.000           counts
ACCPMD5Benchmark.test:·gc.time             avgt    5     4.000               ms