避免JVM预热时间

9

如果我正在设计一个排序算法测试,我可以用这种方式避免JVM预热吗?谢谢!

double count = 0;
double start, end;
for(int r = 0; r < warmup; r++) {
    // do test
}
for(int t = 0; t < runs; t++){
    start = System.nanoTime();
    // do test
    end = System.nanoTime();
    count += start - end;
}
double avg = count/avg

2
你还在尝试对5000个元素进行基准测试吗?或者你已经决定遵循之前问题中给出的建议了吗?如果你已经决定遵循那个建议,你应该接受其中一个答案。 - Anon
4个回答

8
JVM热身通常指JVM查找热点并对代码的这些部分进行JIT编译所需的时间。如果您运行实际测试几百(实际上我相信是几千)次,那么您应该已经做得很好了。但是,即使这样做,也没有任何保证。您需要尝试使用特定的JVM来确定在重要部分被JIT编译之前需要完成多少工作等问题。
这个小案例研究中,JIT编译在调用1700次后开始启动。

嗯,但是如果循环实际上正在运行排序测试呢? - Martin Algesten
啊,抱歉。我没有意识到你实际上是在初始循环中运行测试。是的,那应该会更好。我会更新我的答案。 - aioobe
@aioobe JMH 执行预热迭代。预热迭代真正意味着什么?它是为了预热代码所需的操作次数吗? - Govinda Sakhare

4
如果我正在设计一个排序算法的测试,我可以通过这种方式避免JVM热身吗?
首先要说一下的是,你不应该避免JVM热身。它是必须的。你要做的是防止JVM热身影响到你的基准测试结果。
回答你的问题,这种方法大致上是正确的,但很难预测在初始循环中需要测试多少次。这可能取决于测试代码、JVM版本和JVM调优参数...还可能有其他因素。
我通常只打印原始时间,通过“肉眼”过滤出具有异常计时值的初始“热身”迭代,然后手动计算平均值。虽然有些笨拙,但它让我有信心已经考虑了热身和其他可能的异常来源。

2
这是一个非常大的领域,但是这里有几个提示:
1)确保您的完整测试(包括迭代循环)在重复调用的子例程中。因此,您的测试具有“父”方法中的for()循环。将其下推到“子”并重复调用它。这允许各种JIT技术真正进行完全优化,而无需进行飞行代码替换(如动态循环转移等)。
2)确保测试在长时间的热身后运行很长时间。如果可能的话,30秒是真正的测量周期的最低要求,经过同样长的热身。例如,SPECjbb等每次迭代运行数分钟,多次迭代。

0

是的。由于预热循环运行实际测试,这意味着所有类等都已加载并且 JIT 编译应该已经运行。


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