JMH(Java Microbenchmark Harness): 是专门用于微基准测试的api工具,我们可以通过JMH来对热点函数进行定量的分析,然后进行优化。
比较典型的应用就是:
* 精准知道某方法的执行时长,以及执行时间t和输入p之间的相关性;
* 比较不同接口实现,查找最佳性能方法
官方地址
先用maven将依赖引入:
<!--JMH性能测试的-->
<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>
我们先来一个简单的样例来了解下JMH:String相加和使用StringBuilder的append方式的性能比较测试。
// BenchmarkMode表示基准测试的模型,Throughput是表示吞吐量,可以得到单位时间内的执行的次数数,另外的一些值:
// AverageTime:每次调用的平均消耗时间。
// SampleTime:随机取样的方式。
// SingleShotTime:只运行一次,往往同时把 warmup 次数设为0,用于测试冷启动时的性能。
// All:所有的模式
@BenchmarkMode(Mode.Throughput)
// 这个设置是为了预热代码,这是考虑了JIT编译机制,使得测试更加符合实际情形,iterations是迭代的次数,也就是执行次数,time是一次迭代需要执行的时间
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
// 这个是正常的代码测试,参数意义和上面一样
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
// 测试进程数
@Threads(5)
// 这个是fork的进程分支数
@Fork(2)
// 这个是基准测试的时间单位
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class JSONBenchmarkTest {
@Benchmark
public void testString(){
String str = "";
for (int i = 0; i < 10; i++) {
str += "a";
}
}
@Benchmark
public void testStringBuilder(){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append("a");
}
}
public static void main(String[] args) throws RunnerException {
Options optional = new OptionsBuilder().include(JSONBenchmarkTest.class.getSimpleName()).build();
new Runner(optional).run();
}
}
测试运行的方式有多种,你也可以生成jar包运行,也可以自己写个测试单元,我们来看看运行结果:
# JMH version: 1.21
# VM version: JDK 1.8.0_241, Java HotSpot(TM) 64-Bit Server VM, 25.241-b07
# VM invoker: C:\Program Files\Java\jdk1.8.0_241\jre\bin\java.exe
# VM options: -javaagent:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.4\lib\idea_rt.jar=56074:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.4\bin -Dfile.encoding=UTF-8
# Warmup: 5 iterations, 1 s each
# Measurement: 5 iterations, 5 s each
# Timeout: 10 min per iteration
# Threads: 5 threads, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.ryoma.test.JSONBenchmarkTest.testString
# Run progress: 0.0