← 返回首页

JMH基准测试框架

📂 java ⏱ 2 min 253 words

JMH基准测试框架

JMH(Java Microbenchmark Harness)是OpenJDK官方的微基准测试框架,用于精确测量Java代码的性能。

基础用法

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class StringBenchmark {

    private String string;
    private StringBuilder sb;

    @Setup
    public void setup() {
        string = "hello world";
        sb = new StringBuilder();
    }

    @Benchmark
    public String stringConcat() {
        String result = "";
        for (int i = 0; i < 100; i++) {
            result += "test";
        }
        return result;
    }

    @Benchmark
    public String stringBuilder() {
        sb.setLength(0);
        for (int i = 0; i < 100; i++) {
            sb.append("test");
        }
        return sb.toString();
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
            .include(StringBenchmark.class.getSimpleName())
            .warmupIterations(5)
            .measurementIterations(10)
            .forks(1)
            .build();
        new Runner(opt).run();
    }
}

基准测试模式

@BenchmarkMode(Mode.Throughput)    // 吞吐量:操作/秒
@BenchmarkMode(Mode.SampleTime)    // 采样时间:随机采样执行时间
@BenchmarkMode(Mode.AverageTime)   // 平均时间:平均每次操作耗时
@BenchmarkMode(Mode.SingleShotTime) // 单次执行:只执行一次
@BenchmarkMode({Mode.AverageTime, Mode.Throughput}) // 多模式

黑洞与编译控制

@State(Scope.Thread)
public class CompilerBenchmark {
    private double value = Math.PI;

    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @Warmup(iterations = 5, time = 1)
    @Measurement(iterations = 10, time = 1)
    @Fork(value = 2, jvmArgsAppend = {"-XX:+UseG1GC"})
    public double measureMath(Blackhole bh) {
        // 防止死代码消除
        double result = Math.sin(value);
        bh.consume(result);
        return result;
    }
}

参数化测试

@State(Scope.Benchmark)
public class ParamBenchmark {
    @Param({"10", "100", "1000", "10000"})
    private int size;

    private int[] data;

    @Setup(Level.Trial)
    public void setup() {
        data = new int[size];
        Random rnd = new Random(123);
        for (int i = 0; i < size; i++) {
            data[i] = rnd.nextInt();
        }
    }

    @Benchmark
    public long sumArray() {
        long sum = 0;
        for (int v : data) sum += v;
        return sum;
    }

    @Benchmark
    public long parallelSum() {
        return Arrays.stream(data).parallel().sum();
    }
}

Maven配置

<plugin>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>1.37</version>
    <scope>provided</scope>
</plugin>

小结

JMH通过精确的控制变量和JVM优化规避,提供了可靠的微基准测试能力,是性能调优的必备工具。