java基准测试




我如何在Java中编写正确的微基准测试? (8)

基准应该测量时间/迭代还是迭代/时间,为什么?

这取决于你想要测试的东西。 如果您对延迟感兴趣,请使用时间/迭代,如果您对吞吐量感兴趣,请使用迭代/时间。

你如何在Java中编写(并运行)一个正确的微基准测试?

我正在寻找代码示例和评论来说明各种需要考虑的事情。

例如:基准应该测量时间/迭代还是迭代/时间,为什么?

相关: 秒表基准测试是否可以接受?


Java基准测试的重要内容是:

  • 在对它进行计时之前,先多次运行代码,以此来预热JIT
  • 确保你运行足够长的时间,以便能够在几秒或更好的几十秒内测量结果
  • 尽管在迭代之间不能调用System.gc() ,但在测试之间运行它是一个好主意,这样每个测试都有望获得一个“干净”的内存空间。 (是的, gc()更像是一种暗示,而非保证,但很可能它真的会在我的经验中被垃圾收集。)
  • 我喜欢显示迭代次数和时间,以及可以缩放的时间/迭代分数,以便“最佳”算法得分1.0,其他得分以相对方式得分。 这意味着您可以长时间运行所有算法,改变迭代次数和时间,但仍可获得可比较的结果。

我只是在写关于.NET基准框架设计的博客。 我有couple 较早的帖子 ,可能会给你一些想法 - 当然不是所有的都适合,但有些可能会。


http://opt.sourceforge.net/ Java Micro Benchmark - 确定计算机系统在不同平台上的比较性能特征所需的控制任务。 可用于指导优化决策并比较不同的Java实现。


为了增加其他优秀的建议,我还要注意以下几点:

对于某些CPU(例如TurboBoost的Intel Core i5系列),温度(以及当前正在使用的内核数量,以及更高的利用率)会影响时钟速度。 由于CPU动态计时,这可能会影响结果。 例如,如果您有单线程应用程序,则最大时钟速度(使用TurboBoost)高于使用所有内核的应用程序。 因此这可能会干扰某些系统上单线程和多线程性能的比较。 请记住,温度和电压也会影响Turbo频率的维持时间。

也许你有一个直接控制的更重要的方面:确保你正在衡量正确的事情! 例如,如果您使用System.nanoTime()来测试特定位的代码,请将调用分配到有意义的位置,以避免测量您不感兴趣的事物。例如,请勿做:

long startTime = System.nanoTime();
//code here...
System.out.println("Code took "+(System.nanoTime()-startTime)+"nano seconds");

问题是,当代码完成时,你没有立即获得结束时间。 相反,请尝试以下操作:

final long endTime, startTime = System.nanoTime();
//code here...
endTime = System.nanoTime();
System.out.println("Code took "+(endTime-startTime)+"nano seconds");

在Java中编写微型基准测试有许多可能的缺陷。

首先:你必须计算出各种事件的时间或多或少是随机的:垃圾收集,缓存效果(文件操作系统和内存CPU),IO等。

第二:在很短的时间间隔内,您无法相信测量时间的准确性。

第三:JVM在执行时优化你的代码。 因此,同一个JVM实例中的不同运行将变得越来越快。

我的建议是:让基准测试运行几秒钟,这比运行时间在毫秒级更可靠。 预热JVM(意味着至少在不测量的情况下运行基准测试一次,JVM可以运行优化)。 并多次运行您的基准(可能是5次)并取中间值。 在新的JVM实例中运行每个微基准测试(调用每个基准测试新Java),否则JVM的优化效果可能影响以后运行的测试。 不要执行那些在热身阶段不执行的东西(因为这会触发类加载和重新编译)。


如果您试图比较两种算法,则在每个算法上至少执行两个基准,交替排列顺序。 即:

for(i=1..n)
  alg1();
for(i=1..n)
  alg2();
for(i=1..n)
  alg2();
for(i=1..n)
  alg1();

在不同通行证的相同算法的运行时间中,我发现了一些明显的差异(有时候是5-10%)。

另外,确保n非常大,以便每个循环的运行时间至少在10秒左右。 迭代次数越多,基准时间内的数字越高,数据越可靠。


确保你以某种方式使用以基准代码计算的结果。 否则你的代码可以被优化。


还应该注意的是,在比较不同的实现时分析微基准的结果也可能很重要。 因此应该进行显着性检验

这是因为在基准测试的大部分运行过程中,实施A可能比实施B更快。 但是A也可能具有更高的价差,因此与B相比, A的衡量业绩收益不会有任何意义。

因此,正确编写和运行微基准测试也很重要,但也要正确分析它。





microbenchmark