Java JMH 基准测试工具( 二 )

然后运行main 方法后控制台日志会输出很长的日志信息 , 在这里是执行了testArrayList 与testLinkedList两个方法的基准测试 , 每个方法都会对应一段日志信息 , 小编在这里将testArrayList 方法 日志信息拆分成两段如下:
第一段包括 JVM 的启动参数配置信息 以及 JMH 的基本配置
/Library/Java/JavaVirtualmachines/jdk1.8.0_74.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=65371: ... 省略路径IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath # JMH version: 1.19# VM version: JDK 1.8.0_74, VM 25.74-b02# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/Home/jre/bin/java# VM options: -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=65371:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8# Warmup: 3 iterations, 1 s each# Measurement: 3 iterations, 1 s each# Timeout: 10 min per iteration# Threads: 1 thread, will synchronize iterations# Benchmark mode: Average time, time/op# Benchmark: com.example.demo.DemoApplicationTestJMH.testArrayList# Run progress: 0.00% complete, ETA 00:00:12# Fork: 1 of 1objc[56915]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/Home/jre/bin/java (0x10d1a44c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10d1e94e0). One of the two will be used. Which one is undefined.# Warmup Iteration1: 101153.611 us/op# Warmup Iteration2: 76302.787 us/op# Warmup Iteration3: 54296.903 us/opIteration1: 57062.920 us/opIteration2: 65024.286 us/opIteration3: 56325.284 us/op分析如下图

Java JMH 基准测试工具

文章插图
 

Java JMH 基准测试工具

文章插图
 
Warmup 可译为 预热的意思 , 在 JMH 中 , Warmup 所做 的事情就是在基准测试代码正式执行测量(度量)前 , 对其进行预热 , 如 JVM运行器的编译、JIT 的优化等等
第二段 就是JMH 对 testArrayList 方法的测试输出信息了
Result "com.example.demo.DemoApplicationTestJMH.testArrayList":59470.830 ±(99.9%) 87999.595 us/op [Average](min, avg, max) = (56325.284, 59470.830, 65024.286), stdev = 4823.555CI (99.9%): [≈ 0, 147470.424] (assumes normal distribution)
Java JMH 基准测试工具

文章插图
 
然后 对于 testLinkedList 方法也会有 相同类似的日志信息只不过是输出的数据不一样 , 当两个方法执行基准测试完成后 最后会有对比信息日志如下:
Result "com.example.demo.DemoApplicationTestJMH.testLinkedList":206870.042 ±(99.9%) 2571061.260 us/op [Average](min, avg, max) = (104680.987, 206870.042, 367640.921), stdev = 140928.543CI (99.9%): [≈ 0, 2777931.302] (assumes normal distribution)# Run complete. Total time: 00:00:16BenchmarkModeCntScoreErrorUnitsDemoApplicationTestJMH.testArrayListavgt359470.830 ±87999.595us/opDemoApplicationTestJMH.testLinkedListavgt3206870.042 ± 2571061.260us/op2.3 对比我期望与 代码清单 1-1 所使用的 StopWatch 计时对比一下时时间  , StopWatch 中输出的是纳秒 , 对应的是 TimeUnit.NANOSECONDS  , 所以我需要将 @OutputTimeUnit 配置的单位修改 , 以使用 JMH 度量后的时间单位输出为纳秒
@OutputTimeUnit(TimeUnit.NANOSECONDS)public class DemoApplicationTestJMH { ...}再次运行度量测试 最终日志如下:
# Run complete. Total time: 00:00:16BenchmarkModeCntScoreErrorUnitsDemoApplicationTestJMH.testArrayListavgt357019569.485 ±88169595.613ns/opDemoApplicationTestJMH.testLinkedListavgt3368470033.556 ± 535285211.800ns/opProcess finished with exit code 0代码清单 1-1 所使用的 StopWatch 日志如下:
---------------------------------------------ns%Task name---------------------------------------------177413718044%arrayList 测试227298885056%linkedList 测试3 参数概述3.1 @BenchmarkMode对应Mode选项 , 可用于类或者方法上 ,  需要注意的是 , 这个注解的value是一个数组 , 可以把几种Mode集合在一起执行 , 还可以设置为Mode.All , 即全部执行一遍
Mode 表示 JMH 进行 Benchmark 时所使用的模式 。通常是测量的维度不同 , 或是测量的方式不同 。目前 JMH 共有四种模式: