maven依赖
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.36</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.36</version>
</dependency>
简单使用
package com.chauncy.benchmark;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
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 BenchmarkTest1 {
double pi = Math.PI;
@Benchmark
public void measure(){
pi++;
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(BenchmarkTest1.class.getSimpleName())
.forks(1)
.build();
new Runner(opt).run();
}
}
执行多个函数
package com.chauncy.benchmark;
import org.openjdk.jmh.annotations.*;
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;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
@State(Scope.Benchmark)
@BenchmarkMode(Mode.All)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1)
@Fork(5)
public class BenchmarkTest2 {
private static final int COUNT = 1 ^ 21;
private byte[] sorted;
private byte[] unsorted;
@Setup
public void setup() {
sorted = new byte[COUNT];
unsorted = new byte[COUNT];
SecureRandom random = new SecureRandom();
random.nextBytes(sorted);
random.nextBytes(unsorted);
Arrays.sort(sorted);
}
@Benchmark
@OperationsPerInvocation(COUNT)
public void sorted(Blackhole bh1, Blackhole bh2) {
for (byte b : sorted) {
if (b > 0) {
bh1.consume(b);
} else {
bh2.consume(b);
}
}
}
@Benchmark
@OperationsPerInvocation(COUNT)
public void unsorted(Blackhole bh1, Blackhole bh2) {
for (byte b : unsorted) {
if (b > 0) {
bh1.consume(b);
} else {
bh2.consume(b);
}
}
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(".*" + BenchmarkTest2.class.getSimpleName() + ".*")
.forks(1)
.build();
new Runner(opt).run();
}
}
@BenchmarkMode(Mode.AverageTime) 运行模式
@BenchmarkMode(Mode.Throughput) 吞吐量模式 获取单位时间内的操作数量
@BenchmarkMode(Mode.AverageTime) 平均时间模式 获取每次操作的平均时间
@BenchmarkMode(Mode.SampleTime) 函数运行时间采样模式
@BenchmarkMode(Mode.SingleShotTime) 单次操作时间
@BenchmarkMode(Mode.All) 采用所有的模式
@OutputTimeUnit(TimeUnit.NANOSECONDS) 报告结果时间单位
@Warmup(iterations = 5,time = 1,timeUnit = TimeUnit.SECONDS) 预热参数
iterations 预热的迭代次数
time预热时间
timeUnit 预热时间单位
batchSize 每个基准方法调用次数
@Measurement(iterations = 5,time = 1,timeUnit = TimeUnit.SECONDS,batchSize = 1) 与预热参数类似
@Fork(5) 整体测试次数
@State(Scope.Benchmark) 配置对象作用域
Scope.Benchmark 基准状态范围
Scope.Group 组状态范围
Scope.Thread 线程状态范围
@OperationsPerInvocation(COUNT) 允许与基准进行多个操作的通信