JMH的@OperationsPerInvocation参数详解

先瞧一个例子

public class JMHSample_11_Loops_OperationsPerInvocation {


    int x = 1;
    int y = 2;

    private int reps(int reps) {
        int s = 0;
        for (int i = 0; i < reps; i++) {
            s += (x + y);
        }
        return s;
    }

    @Benchmark
    @OperationsPerInvocation(1_000)
    public int measureWrong_1000() {
        return reps(1_000);
    }

    @Benchmark
    @OperationsPerInvocation(10_000)
    public int measureWrong_1000_2() {
        return reps(1_000);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_11_Loops_OperationsPerInvocation.class.getSimpleName())
                .forks(1)
                .warmupIterations(1).warmupTime(TimeValue.milliseconds(10))
                .measurementIterations(2).measurementTime(TimeValue.milliseconds(300))
                .build();

        new Runner(opt).run();
    }

}

第2个基准测试,除了@OperationsPerInvocation参数是第1个的10倍,其它都一样。结果中第2个基准测试比第1个快10几倍。
结果:

Benchmark                                Mode  Cnt  Score   Error  Units
JMHSample_11_Loops2.measureWrong_1000    avgt    2  0.028          ns/op
JMHSample_11_Loops2.measureWrong_1000_2  avgt    2  0.002          ns/op

官方说明

OperationsPerInvocation annotations allows to communicate the benchmark does more than one operation, and let JMH to adjust the scores appropriately.
For example, a benchmark which uses the internal loop to have multiple operations, may want to measure the performance of a single operation:

   @Benchmark
   @OperationsPerInvocation(10)
   public void test() {
        for (int i = 0; i < 10; i++) {
            // do something
        }
   }

翻译
OperationsPerInvocation批注允许传达基准测试不止一项操作,并允许JMH适当地调整分数。
例如,使用内部循环进行多个操作的基准测试可能想要衡量单个操作的性能。

补充说明

JMH结果的统计是以操作为单位,如每一个操作的响应时间,单位时间内通过的操作数(吞吐量),一个方法视为一个操作(默认情况@OperationsPerInvocation(1))。你可以手动调整一个方法代表几个操作,如果把操作数设置为10,相同的方法,在输出结果中,吞吐量会提高10倍左右,响应时间快10倍左右。

你可能感兴趣的:(JMH,jmh,基准测试,java)