休息正在减慢我的循环?

时间:2014-11-02 03:53:48

标签: java iteration

我有一个嵌套循环,它迭代数组中两个元素的所有组合。但是,如果两个值之和太大,我想跳到下一个x

这是Java代码片段:

/* Let array be an array of integers
 * and size be equal to its length.
 */

for (int a = 0; a < size; a++)
{
    int x = array[a];

    for (int b = 0; b < size(); b++)
    {
        int y = array[b];

        if ((x + y) < MAX)
        {
            // do stuff with x and y
        }
        else
        {
            // x + y is too big; skip to next x
            break;
        }       
    }
}

这完全符合预期。

但是,如果我将break语句替换为b = size;则会令人惊讶地大约快20%。请注意,通过设置b = size;,内部{ {1}}条件变为false,执行继续到外for循环的下一次迭代。

为什么会这样?似乎a应该更快,因为我认为它会保存一个赋值,跳转和比较。虽然显然没有。

1 个答案:

答案 0 :(得分:2)

  

为什么会这样?似乎休息应该更快......

IMO,最可能的解释是某种JVM预热效果,特别是因为整体时间(120ms对74ms)非常小。如果你将那个循环包裹在另一个循环中,这样你就可以在同一次运行中重复执行时间测量,这个异常很可能会消失。

(只是增加数组大小并不一定会有所帮助。确保你已经考虑到JVM预热异常的最佳方法是使用基准测试框架;例如Caliper。但是,失败将#34;片段&#34;放入方法并重复调用。)

  

...因为我认为它可以保存任务,跳转和比较。虽然显然没有。

根本不清楚。您的Java代码由javac(或您的IDE)编译为字节码。当你运行代码时,它开始解释字节码,然后在一点之后它们被JIT编译器编译成本机代码:

  • JIT编译花费时间(可能)包含在您的时间测量中......以及一个预热异常来源。

  • JIT编译器生成的代码受到解释时收集的统计信息的影响。通常测量的一个问题是分支(例如if测试)是否采用这种方式。这用于进行分支预测......如果正确的话,可以使测试和分支指令序列更快。