Last active
March 19, 2024 22:04
-
-
Save bertm/94f3c97fd138fe075a1f54076c6bd3cf to your computer and use it in GitHub Desktop.
Microbenchmark for Hyphanet Fred's SHA256 wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package freenet.benchmark; | |
import java.lang.invoke.MethodHandles; | |
import java.lang.ref.SoftReference; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.Provider; | |
import java.util.Queue; | |
import java.util.Random; | |
import java.util.concurrent.ConcurrentLinkedQueue; | |
import java.util.concurrent.TimeUnit; | |
import org.openjdk.jmh.annotations.Benchmark; | |
import org.openjdk.jmh.annotations.BenchmarkMode; | |
import org.openjdk.jmh.annotations.Level; | |
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.Threads; | |
import org.openjdk.jmh.annotations.Warmup; | |
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; | |
@Warmup(time = 3) | |
@Measurement(time = 3) | |
@OutputTimeUnit(TimeUnit.SECONDS) | |
@BenchmarkMode(Mode.Throughput) | |
@Threads(4) | |
public class DigestBenchmark { | |
@Benchmark | |
public byte[] pooled(SHA256 sha256, Input input) { | |
MessageDigest digest = sha256.borrowPooledDigest(); | |
try { | |
return digest.digest(input.payload); | |
} finally { | |
sha256.returnPooledDigest(digest); | |
} | |
} | |
@Benchmark | |
public byte[] fresh(SHA256 sha256, Input input) { | |
MessageDigest digest = sha256.createFreshDigest(); | |
return digest.digest(input.payload); | |
} | |
@State(Scope.Thread) | |
public static class Input { | |
@Param({"16", "256", "2048"}) | |
public int payloadLength; | |
public byte[] payload; | |
@Setup(Level.Iteration) | |
public void init() { | |
payload = new byte[payloadLength]; | |
new Random().nextBytes(payload); | |
} | |
} | |
@State(Scope.Benchmark) | |
public static class SHA256 { | |
private final Queue<SoftReference<MessageDigest>> digestPool = new ConcurrentLinkedQueue<>(); | |
private Provider provider; | |
@Setup(Level.Trial) | |
public void init() throws NoSuchAlgorithmException { | |
provider = MessageDigest.getInstance("SHA-256").getProvider(); | |
} | |
public MessageDigest createFreshDigest() { | |
try { | |
return MessageDigest.getInstance("SHA-256", provider); | |
} catch (NoSuchAlgorithmException e) { | |
throw new AssertionError(e); | |
} | |
} | |
public MessageDigest borrowPooledDigest() { | |
SoftReference<MessageDigest> item; | |
while (((item = digestPool.poll()) != null)) { | |
MessageDigest md = item.get(); | |
if (md != null) { | |
return md; | |
} | |
} | |
return createFreshDigest(); | |
} | |
public void returnPooledDigest(MessageDigest digest) { | |
digest.reset(); | |
digestPool.add(new SoftReference<>(digest)); | |
} | |
} | |
public static void main(String[] args) throws RunnerException { | |
Options opt = new OptionsBuilder() | |
.include(MethodHandles.lookup().lookupClass().getSimpleName()) | |
.forks(1) | |
.build(); | |
new Runner(opt).run(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Generate a Maven project for running the benchmark as follows (this will create a project directory
fred-benchmark
):Now add the benchmark by adding this benchmark class to
fred-benchmark/src/main/java/freenet/benchmark
.Then package & run:
cd fred-benchmark mvn clean package java -cp target/benchmarks.jar freenet.benchmark.DigestBenchmark