java—如何使用jmh在基准测试中顺序运行方法?

kx7yvsdv  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(374)

在我的场景中,基准测试中的方法应该在一个线程中按顺序运行,并按顺序修改状态。
例如,有一个 List<Integer> 打电话 num 在基准课上。我想要的是:首先,快跑 add() 在列表中添加数字。然后,快跑 remove() 从列表中删除号码。
调用顺序必须是 add() --> remove() . 如果 remove() 在之前运行 add() 或者它们同时运行,会引发异常,因为列表中没有元素。
也就是说, add() 以及 remove() 必须在一个线程中顺序调用。
为了使用jmh控制方法的顺序,我了解到这些方法是按字典顺序运行的。我尝试了以下代码:

@State(Scope.Group)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 10)
public class ListBenchmark {

    private List<Integer> num;

    public static void main(String[] args) throws RunnerException {
        Options options = new OptionsBuilder()
                .verbosity(VerboseMode.NORMAL)
                .syncIterations(true)
                .threads(1)
                .include(".*" + ListBenchmark.class.getCanonicalName() + ".*")
                .build();

        new Runner(options).run();
    }

    @Setup(Level.Invocation)
    public void setup() throws Exception {
        num = new ArrayList<>();
    }

    @Benchmark
    @BenchmarkMode(Mode.SingleShotTime)
    @Group("num")
    public void add() throws Exception {
        num.add(1);
    }

    @Benchmark
    @BenchmarkMode(Mode.SingleShotTime)
    @Group("num")
    public void remove() throws Exception {
        num.remove(0);
    }
}

但它不起作用,因为 add 方法和步骤 remove 方法同时运行。在某些情况下 remove 在之前运行 add 并提出 IndexOutOfBoundsException .
如何使用jmh在基准测试中顺序运行方法?

9bfwbjaz

9bfwbjaz1#

你从一个错误的前提开始,所有的事情都因此而失败。你可以从作者这里看到更广泛的解释。你想要不对称的对称。
如果你想知道要花多少钱 add -> remove 把它们放在同一个地方 @Benchmark ,个人也一样 add 或者 remove 通过不同的 State . 例如:

@State(Scope.Thread)
public static class BothAddAndRemove {

    List<Integer> num;

    @Setup(Level.Invocation)
    public void setup() throws Exception {
        num = new ArrayList<>();
    }
}

@State(Scope.Thread)
public static class RemoveOnly {

    List<Integer> num;

    @Setup(Level.Invocation)
    public void setup() throws Exception {
        num = new ArrayList<>();
        num.add(1);
    }
}

@Fork(25)
@Benchmark
@BenchmarkMode(Mode.SingleShotTime)
public int add(BothAddAndRemove both) {
    both.num.add(1);
    return both.num.remove(0);
}

@Fork(25)
@Benchmark
@BenchmarkMode(Mode.SingleShotTime)
public int removeOnly(RemoveOnly removeOnly) {
    return removeOnly.num.remove(0);
}

相关问题