JMH:从@State类的@Setup方法访问BenchmarkParams

时间:2016-07-08 13:56:23

标签: java benchmarking microbenchmark jmh

是否可以访问nestedletters[j for j in letters]['a']BenchmarkParams中的@Setup,如果该类作为参数传递给@State(Scope.Benchmark)

最小代码示例(实际使用情况更复杂,但这再现了我的问题):

@Benchmark

有一个基本JMH sample,但不是@State( Scope.Benchmark ) public class Test { @Setup public void setUp( BenchmarkParams params ){} @Benchmark public void nothing( Test test ){} } 传递到@State方法

的地方

我想访问@Benchmark中的BenchmarkParams来检索/记录我根据JMH @Setup值创建的每个基准配置数据

使用上面的示例代码:

  1. 定义@Param名为@State(Scope.Benchmark)的类< --- works
  2. 定义名为Test< --- works
  3. @Benchmark方法
  4. nothing()个实例传递给@State方法< --- FAILS!
  5. 这是错误:

    @Benchmark

    欢迎任何帮助!

    [编辑1]

    仅供参考,在我的实际代码中还有一个[ERROR] /Users/.../jmh-benchmarks/target/generated-sources/annotations/test/generated/Test_nothing_jmhTest.java:[390,16] method setUp in class test.Test cannot be applied to given types; required: org.openjdk.jmh.infra.BenchmarkParams found: org.openjdk.jmh.infra.generated.BenchmarkParams_jmhType,org.openjdk.jmh.infra.generated.BenchmarkParams_jmhType reason: actual and formal argument lists differ in length 类,更像是:

    @State(Scope.Thread)

    [编辑2]

    从JMH 1.3开始,这不再是一个问题

1 个答案:

答案 0 :(得分:2)

As explained in question, passing BenchmarkParams into @Setup of TestBasecauses JMH build failures

It seems to be related to having DAGs of @State classes

Passing BenchmarkParams into a @State(Scope.Benchmark) class that is not part of the "main" DAG (e.g., @State(Scope.Benchmark)->@State(Scope.Thread)->@Benchmark) branch seems to resolve that problem

For example,

@State( Scope.Benchmark )
public abstract class TestBase
{
    @Setup
    public void setUp( BenchmarkParamsState state )
    {
        // do something with state.someParam
    }

    @State( Scope.Benchmark )
    public static class BenchmarkParamsState
    {
        String someParam;

        @Setup
        public void setUp( BenchmarkParams params )
        {
            // set someParam based on contents of params
        }
    }
}

@State( Scope.Benchmark )
public class TestImpl extends TestBase
{
    @State( Scope.Thread )
    public static class ThreadState 
    {
        @Setup
        public void setUp( TestImpl state ){}
    }

    @Benchmark
    public void nothing( ThreadState state ){}
}

In addition, because BenchmarkParamsState is part of the greater DAG (due to being passed into @Setup of TestBase) its @Setup still occurs once for every @Benchmark

[EDIT]

As of JMH 1.3 this is no longer a problem