2010-12-03 90 views
7

如果我正在设计排序算法的测试,我可以这样做,以避免JVM热身?谢谢!避免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 2010-12-03 13:38:32

+0

非常感谢,我会那样做 – Ang 2010-12-03 13:50:01

回答

5

JVM热身通常指的是JVM找到热点和JIT代码的这些部分所需的时间。如果你运行几百次(实际上相当于几千次)的实际测试,那么你应该相当不错。

但是你应该知道,即使你这样做,也没有保证。您必须尝试使用​​特定的JVM来确定在关键部件被打开之前需要做多少工作等等。


this little case study JIT编译在1700次调用后踢了。

0

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

3

如果我正在设计排序算法测试,我可以这样做,以避免JVM热身?

第一次有一些pedantry。您不应该避免 JVM热身。它需要发生。你试图做的是防止的JVM热身扭曲你的基准测试结果。

要回答你的问题,这种方法大致是正确的,但是很难预测你需要在初始循环中做多少次测试。它很可能取决于测试代码,JVM版本和JVM调优参数......以及其他可能的事情。

我通常所做的只是打印原始时间,过滤出“看不见”异常计时值的初始“热身”迭代,然后手动计算平均值。这是笨重的,但它给了我一些信心,我已经解释了热身和其他可能的异常来源。

2

这是一个非常大的区域,但这里有几个技巧:

1)确保全面测试(包括迭代循环)中被重复调用的子程序。所以你的测试在“父”方法中有for()循环。将它推到一个“孩子”并反复调用。这使得各种JIT技术能够真正做到完全优化,而无需进行飞行代码替换(dynamic loop transfer等)。

2)确保长时间热身后测试运行很长时间。如果可能的话,经过同样长时间的热身之后,30秒对于实际测量时间是最小的。例如,SPECjbb等,每次迭代运行几分钟,进行多次迭代。