在使用Java编程过程中,我们对于一些代码调用的细节有多种编写方式,但是不确定它们性能时,往往采用重复多次计数的方式来解决。但是随着JVM不断的进化,随着代码执行次数的增加,JVM会不断的进行编译优化,使得重复多少次才能够得到一个稳定的测试结果变得让人疑惑,这时候有经验的同学就会在测试执行前先循环上万次并注释为预热。
没错!这样做确实可以获得一个偏向正确的测试结果,但是我们试想如果每到需要斟酌性能的时候,都要根据场景写一段预热的逻辑吗?当预热完成后,需要多少次迭代来进行正式内容的测量呢?每次测试结果的输出报告是不是都需要用System.out
来输出呢?
其实这些工作都可以交给 JMH (the Java Microbenchmark Harness) ,它被作为Java9的一部分来发布,但是我们完全不需要等待Java9,而可以方便的使用它来简化我们测试,它能够照看好JVM的预热、代码优化,让你的测试过程变得更加简单。
开始
首先在项目中新增依赖,jmh-core
以及jmh-generator-annprocess
的依赖可以在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>
</dependency>
创建一个Helloworld
类,里面只有一个空方法m()
,标注了@Benchmark
的注解,声明这个方法为一个微基准测试方法,JMH 会在编译期生成基准测试的代码,并运行它。
public class Helloworld {
@Benchmark
public void m() {
}
}
接着添加一个main入口,由它来启动测试。
public class HelloworldRunner {
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include("Helloworld")
.exclude("Pref"