JMH未执行全部基准测试问题咨询:8个基准方法中4个未运行,获取类方法未执行
为什么JMH中部分基准方法未执行?
核心原因:同一Group内的基准方法参数不兼容
你把添加操作和获取操作的基准都标记为@Group("g1"),但两类方法的参数列表不一致:
- 添加类方法:仅接收
IndexedLinkedListState参数 - 获取类方法:接收
IndexedLinkedListState + Blackhole参数
JMH要求同一个@Group下的所有基准方法必须拥有兼容的参数列表——因为组内方法会被并发调度,JMH需要为每个线程提供统一的参数上下文。参数不匹配时,JMH无法完成绑定,就会跳过那些不符合要求的方法。
解决方案
方案1:将不同操作的基准分到独立Group
把添加类和获取类基准分别放在不同的Group中,各自配置线程数:
// 添加类基准保持独立Group @Benchmark @Warmup(iterations = 1, time = 2, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 1) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) @Fork(0) @Group(value = "addGroup") @GroupThreads(1) public void Benchmark_1A_profileAddLastRoddeList(IndexedLinkedListState state) { profileAddLast(state.list, ADD_LAST_OPERATIONS, state.random); } // 获取类基准改用新Group @Benchmark @Warmup(iterations = 1, time = 2, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 1) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) @Fork(0) @Group(value = "getGroup") @GroupThreads(1) public void Benchmark_1B_profileGetRoddeList(IndexedLinkedListState state, Blackhole blackhole) { profileGet(state.list, GET_OPERATIONS, state.random, blackhole); }
方案2:统一Group内方法的参数列表
如果你确实需要两类操作在同一个Group内并发执行,给所有添加类方法也加上Blackhole参数(即使方法内部不用它),保证参数列表一致:
@Benchmark @Warmup(iterations = 1, time = 2, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 1) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) @Fork(0) @Group(value = "g1") @GroupThreads(1) // 新增Blackhole参数,和获取类方法保持一致 public void Benchmark_1A_profileAddLastRoddeList(IndexedLinkedListState state, Blackhole blackhole) { profileAddLast(state.list, ADD_LAST_OPERATIONS, state.random); }
其他排查点
如果上述方案解决不了问题,可以检查以下几点:
- 确认
GET_OPERATIONS常量的值是否大于0:如果值为0,profileGet方法内没有实际执行逻辑,JMH可能会跳过该基准。 - 检查
profileGet方法是否正确使用Blackhole:必须调用blackhole.consume(结果)来避免JIT优化掉整个方法逻辑,否则JMH可能认为该方法没有测量价值。 - 检查JMH运行命令:是否通过
-include、-exclude等参数过滤掉了获取类基准方法。
内容的提问来源于stack exchange,提问作者coderodde
相关产品推荐
相关产品推荐

