Java效率比较:2个循环,2个条件VS 1循环,4个条件

时间:2013-11-25 13:12:51

标签: java for-loop performance

我必须搜索一个对象列表,以找到两个属性的2个较低值和2个较大值。在Java中更有效:一旦要求4个值检查列表或两次检查2检查列表?根据我的经验,1循环应该更好,但可能有我可能不知道的编译优化。

这是单循环的代码:

Cell[] getEdges(List<Cell> coordinateList)
{
    int minX = coordinateList.get(0).getX;
    int minY = coordinateList.get(0).getY;
    int maxX = coordinateList.get(0).getX;
    int maxY = coordinateList.get(0).getY;

    Cell[] edgePair = new Cell[2];

    For(Cell currentCell: List<Cell> coordinateList)
    {
        if(currentCell.getX()<minX)
        {
            minX = currentCell.getX();
        }
        if(currentCell.getY()<minY)
        {
            minY = currentCell.getY();
        }
        if(currentCell.getX()>maxX)
        {
            maxX = currentCell.getX();
        }
        if(currentCell.getY()>maxY)
        {
            maxY = currentCell.getY();
        }
    }

    edgePair[0] = new Cell(minX, minY);
    edgePair[1] = new Cell(maxX, maxY);

    return edgePair;
}

这是2个循环的代码(最大值相同,只是更改条件)

Cell getMinEdge(List<Cell> coordinateList)
{
    int minX = coordinateList.get(0).getX;
    int minY = coordinateList.get(0).getY;

    For(Cell currentCell: List<Cell> coordinateList)
    {
        if(currentCell.getX()<minX)
        {
            minX = currentCell.getX();
        }
        if(currentCell.getY()<minY)
        {
            minY = currentCell.getY();
        }
    }

    return new Cell(minX, minY);
}

提前感谢任何建议。

2 个答案:

答案 0 :(得分:4)

我的直觉是,带有一个循环的代码版本应该比带有两个循环的版本快。 (假设您首先纠正语法错误!)我怀疑优化器是否能够将两个循环合并为一个,并且执行两次列表迭代将花费比执行一次更长的时间。

但是,我给你的建议是:

  • 不要过分依赖你(或我或其他人)的直觉来告诉你哪些更有效率。

  • 不要花太多时间在前面思考什么可能/会/应该最快。

相反:

  • 以简单,自然的方式编写代码,然后使用 real 输入对测量应用程序的性能进行基准测试。 (或者是对真实的近似。)

  • 如果性能测量表明需要更快,那么只花时间尝试让代码更快。

  • 一旦确定需要进行优化,请使用分析器告诉您要关注的代码部分。不要依赖你的直觉,因为直觉往往是错误的。

答案 1 :(得分:1)

虽然我非常同意早期的微观优化很糟糕,但这是考虑两种不同算法的情况。算法确实是表现好坏的因素,而不是像(++ x)或(x ++)或(x + = 1)更“有效”的问题。 因此,问题为+1。

(话虽如此,很可能,你的坐标列表中只有很多项目,即使是不太理想的算法也不会以任何明显的方式延迟程序。)

概括一下,当你需要以n不同方式缩小k大小列表时,最好是k单独减少或单个减少结合k方式的缩减。

答案是,如果可能的话,应该努力将k缩减合并为一个。或者,简而言之:如果可能的话,避免重复循环。

我想指出这只是一个的建议。例如,如果您已经有2种方法来确定最小值和最大值,那么在一次运行中编写第3个方法可能就不值得了。 (除非事实证明这是绝对的性能杀手。)

但是在这种情况下,你可以选择并在一个循环中将它们组合在一起也是最合乎逻辑的,因此也是最容易理解的事情。

如果我看到这样的代码

for (X x: xs) { maxX = ...; }
for (X x: xs) { maxY = ...; }

我会在第二行问自己:“他为什么不在第一个循环中这样做?” 然后我会再次检查前面的代码,看看我是否忽略了阻止立即计算maxY的东西。因为我找不到任何东西,所以我不得不以某种方式接受它......但仍然觉得我可能忽略了某些东西。