微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何抑制在 jmh 基准测试中打印到控制台的方法的输出?

如何解决如何抑制在 jmh 基准测试中打印到控制台的方法的输出?

我正在使用 jmh 来比较在控制台打印大量内容的几种方法性能。事实上,这些是 fizzbazz 问题的不同解决方案。

fizzbuzz 的每个实现都是一个类,它实现了 FizzBazz 接口并有一个 print() 方法。所有这些实现都被编译到一个单独的 jar 中。

我试图在我的基准测试中抑制此方法输出。因此,我需要在运行基准测试之前用数组替换输出流,并在完成后将其返回。

如果我在每个基准方法中都这样做,就像这样:

@Benchmark
public void naivetest() {
    PrintStream originalOut = System.out;
    ByteArrayOutputStream outContent = new ByteArrayOutputStream();
    System.setout(new PrintStream(outContent));

    new NaiveFizzBuzz().print(N); // N is upper limit
    
    System.setout(originalOut);
}

然后一切正常。但这是一堆重复的代码,我不想摆脱它。此外,这段代码会破坏测量,因为每次运行测试时都会调用它。

我正在尝试使用 state 来完成我的任务。

@State(Scope.Benchmark)
public static class MyState {
    private PrintStream originalOut;

    @Setup
    public void doSetup() {
        originalOut = System.out;
        ByteArrayOutputStream outContent = new ByteArrayOutputStream();
        System.setout(new PrintStream(outContent));
    }

    @TearDown
    public void doTearDown() {
        System.setout(originalOut);
    }
}

我的基准是这样的:

@Benchmark
public void naivetest() {
    new NaiveFizzBuzz().print(N);
}

// Lots of similar benchmarks here...

但它不起作用。

如何将用于替换输出流的所有代码放在一个地方,以便在每次测试运行之前自动执行?

解决方法

我找到了解决问题的方法。事实上,我需要将我的状态对象作为参数传递给每个基准。

@Benchmark
public void naiveTest(MyState state) {
    new NaiveFizzBuzz().print(N);
}

完全按照我的需要工作。

很遗憾,jmh 的文档不是很人性化,所以我花了一段时间才找到这一点。

我做了一些研究,得出的结论是可以回答我自己的问题。如果不是这种情况,请纠正我。然后我会编辑问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。