JMH允许用户自定义一些计数器,
然后可以把你自己的计数器内容加入到执行结果中

怎么用

看示例

根据自定义的计数器输出吞吐量

  • @State注解上, 添加一个 @AuxCounters注解

    1. @State(Scope.Thread)
    2. @AuxCounters( //专门放在@State对象上;Type有两种:
    3. AuxCounters.Type.OPERATIONS // 1.OPERATIONS: 报表吞吐量;
    4. )
    5. public static class OpCounters {
    6. // These fields would be counted as metrics
    7. public int case1; //输出表格
    8. public int case2; //输出表格
    9. // This accessor will also produce a metric
    10. public int total() {
    11. return case1 + case2;
    12. }
    13. }

最后输出报表的时候, 会加三项

  1. case1
  2. case2
  3. total

只要是数字类型的就会被打印

  1. @Benchmark
  2. public void splitBranch(OpCounters counters) {
  3. if (Math.random() < 0.1) { //取值范围 [0,1)
  4. counters.case1++; //P=0.1
  5. } else {
  6. counters.case2++; //P=0.9
  7. }
  8. }

最后输出:

  1. Benchmark Mode Cnt Score Error Units
  2. Sample_23_AuxCounters.splitBranch thrpt 48653307.461 ops/s
  3. Sample_23_AuxCounters.splitBranch:case1 thrpt 4868516.203 ops/s
  4. Sample_23_AuxCounters.splitBranch:case2 thrpt 43784791.257 ops/s
  5. Sample_23_AuxCounters.splitBranch:total thrpt 48653307.461 ops/s

是不是多了三个

根据自定义的计数器输出次数

  1. @State(Scope.Thread)
  2. @AuxCounters(
  3. AuxCounters.Type.EVENTS //2.EVENTS:报表展示计数;
  4. )
  5. public static class EventCounters {
  6. // This field would be counted as metric
  7. public int wows;
  8. }
  1. @Benchmark
  2. public void runSETI(EventCounters counters) {
  3. float random = (float) Math.random();
  4. float wowSignal = (float) Math.PI / 4; //概率很低
  5. if (random == wowSignal) {
  6. // WOW, that's unusual.
  7. counters.wows++;
  8. }
  9. }

输出:

  1. Benchmark Mode Cnt Score Error Units
  2. Sample_23_AuxCounters.runSETI thrpt 55058210.016 ops/s
  3. Sample_23_AuxCounters.runSETI:wows thrpt 3.000 #

什么场景需要使用呢?

  1. 如果我们要统计Benchmark里面的代码执行概率, 可以用它来评估
  2. 如果我们要统计Benchmark里面某些特殊的操作, 总共操作了多少次, 可以用它来评估

更加丰富我们的报表

可能用不上, 但是你既然学了JMH, 那么在看最终报表的时候起码要看懂吧
这里只是给你点印象, 记不住没关系, 后面遇到了再回来看看 体会体会