一、背景
在benchmark的世界里头,分为广义的benchmark和狭义的benchmark(即microbenchmark,中文人称微基准测试)。
广义的benchmark涵盖很多方面,对于一个分层的web系统来说,可能包括操作系统的、数据库的、网络交互的、应用系统里头的benchmark;microbenchmark是针对一个相对的小的方面来说的,比如针对java系统的microbenchmark,针对数据库负载能力的microbenchmark,针对web服务器的microbenchmark等等。
而在java里头的microbenchmark又牵涉到许多java编译优化方面的benchmark处理,比如针对普通java应用系统的性能测试,需要预热阶段,是的JIT的优化能达到效果,系统进入稳定状态,尽量控制变量,好得出实验结果。当然,如果本身就是要测试jvm编译优化的,那就可以省去这步了。
因而,如何知道系统什么时候进入稳定状态,JIT的优化不会对实现结果造成不必要的干扰,就得程序去处理预热阶段,可能比较复杂,不过还好,有人搞了一个JMH的code tool,是的在java里头进行microbenchmark变得异常方便。
二、工具
1、jmh
JMH (Java Micro-benchmarks Harness or Juicy Munchy Hummus, hard to say as they don't tell you on the site) is the latest and as it comes out of the workshop of the very people who work hard to make the OpenJDK JVM fly it promises to deliver more accuracy and better tooling then most.
2、使用方式
(1)基于maven的配置
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>0.4.2</version>
</dependency>
(2)HELLO WORLD
public class JMHSample_01_HelloWorld {
@GenerateMicroBenchmark
public void wellHelloThere() {
// this method was intentionally left blank.
}
}
(3)命令行运行
mvn clean install
java -jar target/benchmarks.jar JMHSample_01`
(4)main方法里头运行
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(JMHSample_01_HelloWorld.class.getSimpleName())
.forks(1)
.build();
new Runner(opt).run();
}
三、参数说明
1、Mode.Throughput
在有时限的迭代里头,该方法能被调用多少次
2、Mode.AverageTime
方法平均执行时间
3、Mode.SampleTime
对方法执行时间进行采样计算
4、Mode.SingleShotTime
方法的单次调用时间/一次批处理的总调用时间
注意点:
从@State对象读取测试输入并返回计算的结果,方便JMH对冗余代码进行消除;
如果是测试方法的性能,则避免通过在方法内循环(重复执行方法内原来代码),这样造成方法方法调用次数的减少,结果不准确,应该把循环调用放在方法外头。
examples的话,参考官网:
http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/