忆梦|Java JMH 基准测试工具( 三 )


忆梦|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 共有四种模式:

  • Throughput: 整体吞吐量 , 例如“1秒内可以执行多少次调用” 。
  • AverageTime: 调用的平均时间 , 例如“每次调用平均耗时xxx毫秒” 。
  • SampleTime: 随机取样 , 最后输出取样结果的分布 , 例如“99%的调用在xxx毫秒以内 , 99.99%的调用在xxx毫秒以内”
  • SingleShotTime: 以上模式都是默认一次 iteration 是 1s , 唯有 SingleShotTime 是只运行一次 。 往往同时把 warmup 次数设为0 , 用于测试冷启动时的性能 。
3.2 Iteration 与 WarmupIteration 是 JMH 进行测试的最小单位 。 在大部分模式下 , 一次 iteration 代表的是一秒 , JMH 会在这一秒内不断调用需要 benchmark 的方法 , 然后根据模式对其采样 , 计算吞吐量 , 计算平均执行时间等 。


推荐阅读