maven引入
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.19</version>
<scope>provided</scope>
</dependency>
示例代码
package com.dcy.domain.course.provider.controller;
import org.openjdk.jmh.annotations.*;
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.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.TimeUnit;
// Throughput(方法吞吐量)则刚好与AverageTime相反,它的输出信息表明了在单位时间内可以对该方法调用多少次。
//SampleTime(时间采样)的方式是指采用一种抽样的方式来统计基准测试方法的性能结果,与我们常见的Histogram图(直方图)几乎是一样的,它会收集所有的性能数据,并且将其分布在不同的区间中。
//SingleShotTime主要可用来进行冷测试,不论是Warmup还是Measurement,在每一个批次中基准测试方法只会被执行一次,一般情况下,我们会将Warmup的批次设置为0。
//@BenchmarkMode({Mode.AverageTime, Mode.Throughput})
@BenchmarkMode(Mode.AverageTime)
//@BenchmarkMode(Mode.All)
//输出时间单位
@OutputTimeUnit(TimeUnit.MICROSECONDS)
//所谓线程独享的State是指,每一个运行基准测试方法的线程都会持有一个独立的对象实例,该实例既可能是作为基准测试方法参数传入的,也可能是运行基准方法所在的宿主class,将State设置为
//Scope.Thread一般主要是针对非线程安全的类
// Scope.Group 将Test设置为线程组共享的
// Scope.Benchmark设置为线程间共享的资源
@State(Scope.Benchmark)
//@Measurement(iterations = 5) // 度量5个批次
//@Warmup(iterations = 3) // 预热3个批次
//设置5个线程运行基准测试方法
@Threads(5)
public class TestClass {
private final static String DATA = “DUMMY DATA”;
private List arrayList;
private List linkedList;
//同时多次比对
@Param({“1”, “2”, “3”, “4”})
private int type;
private Map<Long, Long> map;
@Setup(Level.Iteration)
public void setUp() {
this.arrayList = new ArrayList<>();
this.linkedList = new LinkedList<>();
switch (type) {
case 1:
this.map = new ConcurrentHashMap<>();
break;
case 2:
this.map = new ConcurrentSkipListMap<>();
break;
case 3:
this.map = new Hashtable<>();
break;
case 4:
this.map = Collections.synchronizedMap(
new HashMap<>());
break;
default:
throw new IllegalArgumentException("Illegal map type.");
}
}
// 只需要一个基准测试方法即可
@Benchmark
public void test() {
this.map.put(System.nanoTime(), System.nanoTime());
}
// 在线程组"test"中,有三个线程将不断地对Test实例的write方法进调用
// @GroupThreads(3)
// @Group(“test1”)
@Benchmark
public List arrayListAdd() {
this.arrayList.add(DATA);
return arrayList;
}
// @GroupThreads(3)
// @Group(“test2”)
@Benchmark
public List linkedListAdd() {
this.linkedList.add(DATA);
return this.linkedList;
}
public static void main(String[] args) throws RunnerException {
final Options opts = new
OptionsBuilder().include(TestClass.class.getSimpleName())
// 度量执行的批次为5,也就是 说在这5个批次中,对基准方法的执行与调用将会纳入统计
.measurementIterations(5)
// 在真正的度量之前,首先会对代码 进行3个批次的热身,使代码的运行达到JVM已经优化的效果
.warmupIterations(3)
.forks(1)
.build();
new Runner(opts).run();
}
}