当前位置: 首页 > 面试题库 >

JMH:在所有基准测试中使用相同的静态对象

颜德馨
2023-03-14
问题内容

我有一个构造一些复杂数据的类(想象一个大的XML或JSON结构-
这样的事情)。建造它需要时间。所以我想构造一次,然后在所有测试中使用相同的数据。目前,我基本上在一个public static定义了class的类中定义了一个对象实例main,然后在测试中显式引用它(代码是一个非常简化的示例):

public class Data 
{
    // This class constructs some complicated data 
}

public class TestSet 
{
    public static final Data PARSE_ME = new Data(...);

    public static void main(String[] args) throws RunnerException 
    {
        Options opt = new OptionsBuilder()
                .include(".*ParserTest") // several tests
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

@State(Scope.Thread)
public class SomeParserTest
{
    @Setup(Level.Iteration)
    public void setup()
    {
        Parser parser = new Parser(TestSet.PARSE_ME);
    }

    @Benchmark
    public void getId() 
    {
        parser.getId(123);
    }
}

当然这太糟糕了……同样邪恶的选择是创建一个单独的类,以便它可以容纳单个静态对象。使用类似的东西会很好

Options opt = new OptionsBuilder()
    ...
    .param(/*my Data object comes here*/)

param只接受字符串,因此不确定如何将一个对象(更重要的是:该对象的同一实例!)传递给它。

那么,有没有什么比我上面描述的全局对象更优雅?


问题答案:

不幸的是,JMH无法提供在基准之间共享数据的方法。

一方面,当一个基准可以静默修改另一个基准的输入数据时,这打破了基准隔离,从而使比较不正确。这就是为什么你需要@Setup@State每一个基准对象。

但是更重要的是,static当JMH将在其自己的VM中执行每个测试时,在基准之间共享数据的任何技巧(例如,可从这两者访问的字段)都会中断默认的“分支”模式。值得注意的是,您建议的内容static final Data TestSet.PARSE_ME实际上将针对每个对象执行@Benchmark,因为每个新的VM实例都必须进行初始化TestSet;)当然,您可以禁用派生,但这会带来更多无法解决的问题。

因此,最好花一些时间使安装成本更可承受,这样才不会造成极大的痛苦。例如,从磁盘反序列化数据,而不是对其进行计算。或者,只是想出一种更快的计算方法。



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

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

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

  • 我有一个应用程序,我想使用对其进行基准测试。任何有关此集成的参考都将是有用的。

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

  • 我正在使用JMH对自定义集合实现进行性能测试。 我想模仿一个场景,其中读取次数比写入次数大10倍。 我使用了这个非对称基准测试示例,并创建了一个包含10个读取线程和1个写入线程的组: 我使用参数运行测试。在报告中,变量对所有基准测试都是相同的: 这是否意味着实验中的读取次数等于写入次数?如果有,如何正确实施?更一般的问题是:我在这个设置中遗漏了什么吗?