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

使用JMH的简单微基准测试

弘焕
2023-03-14

受另一个关于堆栈溢出的问题的启发,我编写了一个微型基准来检查,什么更有效:

  • 有条件地检查零除数或
  • 捕获和处理ArithmeticException

下面是我的代码:

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {

    private int a = 10;
    // a little bit less obvious than int b = 0;
    private int b = (int) Math.floor(Math.random());

    @Benchmark
    public float conditional() {
        if (b == 0) {
            return 0;
        } else {
            return a / b;
        }
    }

    @Benchmark
    public float exceptional() {
        try {
            return a / b;
        } catch (ArithmeticException aex) {
            return 0;
        }
    }
}

我对JMH完全陌生,不确定代码是否正确。

我的基准是正确的吗?你看到任何错误吗?

旁白:请不要建议询问https://codereview.stackexchange.com.对于Codereview,代码必须已按预期工作。我不确定这个基准是否能按预期工作。

共有1个答案

司马建柏
2023-03-14

我看到的最大的缺失就是任何一种随机性。这将使分支预测更容易完成其工作,这将使这两种方法的速度都快于实际中除以0的速度。

我会对每种方法进行三种变化:

  1. 使用零混合的随机数组,并使用该数组中的索引对基准进行参数化
  2. 使用非零数的随机数组
  3. 所有0

这将使您对总体性能有一个很好的了解,包括分支预测。对于第(1)点,处理0与非0的比率可能也很有趣。

我忘记了JMH是否允许您直接对数组的各个值进行参数化。如果是这样,那么我会使用它。否则,您将不得不对该数组的索引进行参数化。在这种情况下,我还会将所有0放入数组中,以便保留访问是所有测试的一部分。我可能还会创建一个“控件”,它只是访问数组并返回其值,这样您就可以更直接地找出开销。

还有一个小问题:我认为不需要返回浮点数,因为它们只是从除法实际生成的整数转换而来。

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

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

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

  • 我目前有一个JMH基准测试来衡量所有实现相同接口的各种数据结构的性能。基准测试工作正常,但我想为每个基准测试打印一些额外的信息,这些信息描述了我的数据结构在试验前后的状态。 目前,我正在做下面的代码 问题是与JMH的输出混淆。有没有办法避免这种情况,并在JMH完成其试验报告后运行我的打印声明?另一种方法是将其写入一个文件,然后进行合并,但最好得到一个不需要手动合并的报告。

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

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