Using JMH for Java Microbenchmarking: A Comprehensive Guide
This article introduces Java Microbenchmark Harness (JMH), explains why warm‑up is needed, walks through project setup with Maven, demonstrates benchmark code for LinkedList iteration, details common JMH annotations, shows how to run and interpret results, and concludes with practical usage tips, while also mentioning a promotional book giveaway.
In daily development, measuring the performance of code or tools is essential; the author starts with a brief greeting and promotes a holiday giveaway of a 258‑book set for members of a knowledge community.
When testing Java code, the JVM mixes JIT compilation and interpretation, making it hard to determine how many repetitions are needed for stable results, so a warm‑up phase is recommended.
JMH (Java Microbenchmark Harness) is an official OpenJDK tool for micro‑benchmarking at the method level with microsecond precision. Key points include pre‑warming, avoiding dead code elimination, concurrent testing, and proper result presentation.
Typical usage scenarios are quantitative analysis of hot‑spot functions, measuring execution time relative to input variables, and comparing multiple implementations of a function.
Demo Demonstration
The demo shows how to quickly get started with JMH.
1. Test Project Construction
JMH works with Java 9+; the example uses Java 8. The Maven archetype can be generated with the following command:
$ mvn archetype:generate \
-DinteractiveMode=false \
-DarchetypeGroupId=org.openjdk.jmh \
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
-DgroupId=org.sample \
-DartifactId=test \
-Dversion=1.0Alternatively, add the dependencies directly to an existing Maven project:
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>provided</scope>
</dependency>2. Writing Performance Tests
The example benchmarks LinkedList iteration using index‑based loops versus foreach loops:
/**
* @author Richard_yyf
* @version 1.0 2019/8/27
*/
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.SECONDS)
@Threads(Threads.MAX)
public class LinkedListIterationBenchMark {
private static final int SIZE = 10000;
private List
list = new LinkedList<>();
@Setup
public void setUp() {
for (int i = 0; i < SIZE; i++) {
list.add(String.valueOf(i));
}
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void forIndexIterate() {
for (int i = 0; i < list.size(); i++) {
list.get(i);
System.out.print("");
}
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void forEachIterate() {
for (String s : list) {
System.out.print("");
}
}
}3. Executing Tests
Benchmarks can be run by building a JAR and executing it, or directly from an IDE using a main method:
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(LinkedListIterationBenchMark.class.getSimpleName())
.forks(1)
.warmupIterations(2)
.measurementIterations(2)
.output("E:/Benchmark.log")
.build();
new Runner(opt).run();
}4. Reporting Results
Sample output shows throughput (operations per second) for each benchmark method:
Benchmark Mode Cnt Score Error Units
LinkedListIterationBenchMark.forEachIterate thrpt 2 1192.380 ops/s
LinkedListIterationBenchMark.forIndexIterate thrpt 2 206.866 ops/sThe article also lists common JMH annotations such as @BenchmarkMode, @Warmup, @Measurement, @Threads, @Fork, @OutputTimeUnit, @Benchmark, @Param, @Setup, @TearDown, and @State, explaining their purposes and usage examples.
Conclusion
JMH can be applied to benchmark various tools and frameworks (e.g., logging libraries, BeanCopy implementations). The author encourages readers to explore official JMH samples for more examples.
Architect's Tech Stack
Java backend, microservices, distributed systems, containerized programming, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.