From c20e9676c4ba79ff5fa1ac0ee1a818a94abcc43c Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Tue, 15 Nov 2022 13:22:12 +0100 Subject: [PATCH] Add SHA1 benchmark Results on a Mac M1 max: size SHA1Native SHA1Java SHA1Java without with collision collision detection detection [kB] [us/op] [us/op] [us/op] --------------------------------------------- 1 3.662 4.200 4.707 2 7.053 7.868 8.928 4 13.883 15.149 17.608 8 27.225 30.049 35.237 16 54.014 59.655 70.867 32 106.457 118.022 140.403 64 212.712 237.702 281.522 1024 3469.519 3868.883 4637.287 131072 445011.724 501751.992 604061.308 1048576 3581702.104 4008087.854 4831023.563 The last 3 sizes (1, 128, 1024 MB) weren't committed here to limit the total runtime. Bug: 580310 Change-Id: I7d0382fd4aa4c4734806b12e96b671bee37d26e3 --- org.eclipse.jgit.benchmarks/pom.xml | 5 + .../jgit/benchmarks/SHA1Benchmark.java | 99 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SHA1Benchmark.java diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml index 8f5f98921..9e3d68d73 100644 --- a/org.eclipse.jgit.benchmarks/pom.xml +++ b/org.eclipse.jgit.benchmarks/pom.xml @@ -43,6 +43,11 @@ org.eclipse.jgit ${project.version} + + org.eclipse.jgit + org.eclipse.jgit.junit + ${project.version} + diff --git a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SHA1Benchmark.java b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SHA1Benchmark.java new file mode 100644 index 000000000..a2b59339b --- /dev/null +++ b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SHA1Benchmark.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2022, Matthias Sohn and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.benchmarks; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jgit.junit.MockSystemReader; +import org.eclipse.jgit.util.SystemReader; +import org.eclipse.jgit.util.sha1.SHA1; +import org.eclipse.jgit.util.sha1.SHA1.Sha1Implementation; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@State(Scope.Thread) +public class SHA1Benchmark { + + @State(Scope.Benchmark) + public static class BenchmarkState { + + @Param({ "1", "2", "4", "8", "16", "32", "64" }) + int size; + + @Param({ "false", "true" }) + boolean detectCollision; + + @Param({ "java", "jdkNative" }) + String impl; + + private SecureRandom rnd; + + byte[] content; + + @Setup + public void setupBenchmark() { + SystemReader.setInstance(new MockSystemReader()); + if (impl.equalsIgnoreCase(Sha1Implementation.JDKNATIVE.name())) { + System.setProperty("org.eclipse.jgit.util.sha1.implementation", + Sha1Implementation.JDKNATIVE.name()); + } + content = new byte[size * 1024]; + try { + rnd = SecureRandom.getInstanceStrong(); + } catch (NoSuchAlgorithmException e) { + // ignore + } + rnd.nextBytes(content); + } + + @TearDown + public void teardown() { + SystemReader.setInstance(null); + rnd = null; + } + } + + @Benchmark + @BenchmarkMode({ Mode.AverageTime }) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + @Warmup(iterations = 2, time = 100, timeUnit = TimeUnit.MILLISECONDS) + @Measurement(iterations = 2, time = 5, timeUnit = TimeUnit.SECONDS) + @Fork(1) + public void testSHA1(Blackhole blackhole, BenchmarkState state) { + SHA1 hash = SHA1.newInstance(); + hash.setDetectCollision(state.detectCollision); + hash.update(state.content); + blackhole.consume(hash.digest()); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(SHA1Benchmark.class.getSimpleName()) + .forks(1).jvmArgs("-ea").build(); + new Runner(opt).run(); + } +}