Backend Development 12 min read

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.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Using JMH for Java Microbenchmarking: A Comprehensive Guide

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.0

Alternatively, 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/s

The 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.

javaperformance testingMavenannotationsMicrobenchmarkJMH
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.