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
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml
index 8f5f989..9e3d68d 100644
--- a/org.eclipse.jgit.benchmarks/pom.xml
+++ b/org.eclipse.jgit.benchmarks/pom.xml
@@ -43,6 +43,11 @@
       <artifactId>org.eclipse.jgit</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.eclipse.jgit</groupId>
+      <artifactId>org.eclipse.jgit.junit</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 
   <build>
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 0000000..a2b5933
--- /dev/null
+++ b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SHA1Benchmark.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022, Matthias Sohn <matthias.sohn@sap.com> 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();
+	}
+}