当前位置: 首页 > 知识库问答 >
问题:

打印jmh基准测试的附加输出

赏高格
2023-03-14

我目前有一个JMH基准测试来衡量所有实现相同接口的各种数据结构的性能。基准测试工作正常,但我想为每个基准测试打印一些额外的信息,这些信息描述了我的数据结构在试验前后的状态。

目前,我正在做下面的代码

@Param({"impl0", "impl1", "impl2"})
String dataStructureImplementation;

DataStructureInterface dataStructure;

List<String> inputData;

@Setup(Level.Trial)
public void setUp() {
    switch (dataStructureImplementation) {
        case "impl0":
            dataStructure = new DataStructureImplementation0();
            break;
        case "impl1":
            dataStructure = new DataStructureImplementation1();
            break;
        case "impl2":
            dataStructure = new DataStructureImplementation2();
            break;
        default:
            throw new IllegalArgumentException();
    }
    setUpDataStructure();
    inputData = readInputDataFromFile();
    System.out.println(dataStructure.getStateRepresentation());
}

@TearDown(Level.Trial)
public void tearDown() {
    System.out.println(dataStructure.getStateRepresentation());
}

@Benchmark
@OperationsPerInvocation(1000000)
public void queryDataStructure(Blackhole bh) {
    for (String datum : inputData)
        bh.consume(dataStructure.query(datum));
}

问题是系统的输出。出来println与JMH的输出混淆。有没有办法避免这种情况,并在JMH完成其试验报告后运行我的打印声明?另一种方法是将其写入一个文件,然后进行合并,但最好得到一个不需要手动合并的报告。

共有1个答案

宦琪
2023-03-14

没有开箱即用的方法可以从@Setup和@Teardown方法积累一些自定义格式的输出并将其附加到最终报告中。

一种方法是将所需的输出附加到一个文件中,并在所有基准测试完成后打印其内容。

不过,您需要使用Runner类来运行测试。

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class BenchmarkTestWithMoreOutput {

    public static void main(String[] args) throws RunnerException {

        // This is just a very basic setup just to get an idea
        Options opt = new OptionsBuilder()
                .include(BenchmarkTestWithMoreOutput.class.getSimpleName())
                .forks(2)
                .build();

        Collection<RunResult> results = new Runner(opt).run();

        // Now print your file content. 
        // It will be printed after the default JMH report
   }

    @Benchmark
    public int benchmarkMethod() {
        // code to benchmark
    }
}

RunResult对象包含来自迭代的信息。您可以将其与自定义输出混合并打印一些漂亮的报告。

 类似资料:
  • 我使用JMH对DOM解析器进行基准测试。我得到了非常奇怪的结果,因为第一次迭代实际上比后面的迭代运行得更快 有人能解释为什么会这样吗?此外,百分位数和所有数字意味着什么?为什么在第三次迭代后它开始变得稳定?一次迭代是否意味着整个基准测试方法的一次迭代?下面是我正在运行的方法

  • 受另一个关于堆栈溢出的问题的启发,我编写了一个微型基准来检查,什么更有效: 有条件地检查零除数或 捕获和处理 下面是我的代码: 我对JMH完全陌生,不确定代码是否正确。 我的基准是正确的吗?你看到任何错误吗? 旁白:请不要建议询问https://codereview.stackexchange.com.对于Codereview,代码必须已按预期工作。我不确定这个基准是否能按预期工作。

  • 我正在使用向服务器发送REST请求的自定义Java库为HTTP服务器编写性能测试。在开始时,我正在执行数据准备阶段,以便获得一个要向服务器发送请求的对象列表。 现在,问题是,我可以使用注释测试可以注入基准函数的参数列表: 问题是,我希望通过Java参数列表实现同样的效果,并避免对它们进行迭代。你能告诉我怎么做吗?

  • 我使用jmh来比较在控制台上大量打印的几种方法的性能。事实上,这些都是fizzbazz问题的不同解决方案。 fizzbuzz的每个实现都是一个实现FizzBazz接口的类,并且有一个print()方法。所有这些实现都被编译到一个单独的jar中。 我试图在我的基准测试中抑制这种方法的输出。因此,我需要在运行基准测试之前用数组替换输出流,并在测试完成后返回。 如果我在每个基准方法中执行此操作,如下所示

  • 我是JMH的新手。在运行代码并使用不同的注释之后,我真的不明白它是如何工作的。我使用迭代=1、预热=1、fork=1来查看我的代码将执行一次,但事实并非如此。JMH运行我的代码超过100000次,我不知道为什么。那么,如何控制代码调用的时间?下面是我的代码:(我为测试修复了JMHSample\u 01)

  • 我的最终目标是使用标准Java集合作为基准,为几个Java基本集合库创建一套全面的基准。在过去,我曾使用循环方法编写这类微基准测试。我将我正在进行基准测试的函数放在一个循环中,并迭代100万次,这样jit就有机会预热。我取循环的总时间,然后除以迭代次数,得到一个对我正在进行基准测试的函数的单个调用所需时间的估计值。在最近阅读了JMH项目,特别是这个例子:JMHSample_11_循环之后,我看到了