如何使用JMH测量冷启动的平均时间?

5
在JMH(Java Microbenchmark Harness)中,我们可以使用:
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 10)
@Measurement(iterations = 10)

评估JVM热身后执行的平均时间。

此外,我们可以使用

@BenchmarkMode(Mode.SingleShotTime)
@Measurement(iterations = 1)

如何估测一个执行的"冷启动时间(cold start time)"?可是只执行一次基准测试可能会引入偏差,那么有没有方法可以评估JMH中冷启动的平均时间呢?

1个回答

3
根据Alexey本人的说法(尽管是从2014年开始):
单次测量基准测试最初旨在在多个分支上运行单个测量迭代,以估计“冷”性能的场景。但对于许多情况,特别是如果您仅运行单个分支,则可能希望在那里进行更多的测量迭代,因为会生成更多的样本。
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class AverageSingleShot {

    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
            .include(AverageSingleShot.class.getSimpleName())
            .build();

        new Runner(opt).run();
    }

    @Fork(100)
    @Benchmark
    @BenchmarkMode(Mode.SingleShotTime)
    public int test() {
        return ThreadLocalRandom.current().nextInt() + ThreadLocalRandom.current().nextInt();
    }

}

除了告诉你这个 平均值(请看 100),还有其他事实:
 Benchmark               Mode  Cnt      Score      Error  Units
 AverageSingleShot.test    ss  100  41173.540 ± 2871.546  ns/op
 

您还将获得 百分位数直方图

为什么要使用100次迭代进行测量和预热?这不是适得其反吗? - knittl
1
@knittl编辑。Warmup确实是错误的,但Measurement可能取决于您的测试内容。如果您想测量invokedynamic的次数(在第一次调用时很昂贵)-您可能是正确的,但在上面的测试中,C1编译器不会在100次调用中启动,因此我猜这也被视为“冷”处理。 - Eugene
谢谢你的出色回答,它很有效!我还想知道如何使一个基准测试中的方法在主线程中按顺序运行? - Thesharing
@Thesharing,你可以单独提出一个问题吗? - Eugene
这是另一个问题的链接:https://dev59.com/1r7pa4cB1Zd3GeqPz356。非常感谢您慷慨的帮助。 - Thesharing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接