【问题标题】:Java efficiency comparison: 2 Loops with 2 conditions VS 1 Loop with 4 conditionsJava效率比较:2个2个条件的循环VS 1个4个条件的循环
【发布时间】:2013-11-25 13:12:50
【问题描述】:

我必须搜索对象列表以找到两个属性中较低的 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);
}

提前感谢您的任何建议。

【问题讨论】:

  • 我想你是在比较六个和六个...
  • 为什么要通过您的列表两次使您的代码更快?!
  • 不要推测性能。通常:代码尽可能优雅和干净 - 然后它也会很快!如果速度不够快:使用分析器!其他都是猜测! (你知道投机给世界经济带来了什么......)
  • @Doorknob 这不是那么简单:在某些情况下循环两次可能会更快。例如,检查在交错时可能会争夺缓存。
  • 建议:将所有出现的if (a &lt; min) { min = a; } 替换为min = Math.min(a, min);,这样更易​​于阅读并且可能更快,并使用测试来确定您可以应用哪些其他改进来使您的代码更快。跨度>

标签: java for-loop performance


【解决方案1】:

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

不过,我给你的建议是:

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

  • 不要花太多时间预先考虑什么可以/将会/应该是最快的。

改为:

  • 以简单、自然的方式编写代码,然后用真实输入对其进行基准测试以测量您的应用程序的性能。 (或者一个很好的近似真实值。)

  • 只有在性能测量表明它需要更快时才花时间尝试让代码运行得更快。

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

【讨论】:

    【解决方案2】:

    虽然我强烈同意早期的微优化不好,但这是考虑两种不同算法的情况。算法确实是决定性能好坏的东西,而不是像 (++x) 或 (x++) 或 (x+=1) 中的哪个“更有效”这样的问题。 因此,对该问题 +1。

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

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

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

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

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

    如果我看到这样的代码

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-13
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      • 2018-09-14
      • 2019-03-01
      • 2015-04-11
      • 1970-01-01
      相关资源
      最近更新 更多