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 #408

Closed pengxiaolong closed 1 month ago

pengxiaolong commented 1 month ago

Issue #, if available: #407

Description of changes:

Both java_buffer::from_array and GetByteArrayRegion support consuming a slice of the array by passing offset and length, the change adds a bufOffset arguments to fastDigest to avoid unnecessary array copy in singlePass which needs to invoke fastDigest method.

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

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.