Java效率比较:使用2个条件的2个循环与使用4个条件的1个循环

Java效率比较:使用2个条件的2个循环与使用4个条件的1个循环,java,for-loop,performance,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;

我必须搜索一个对象列表,以找到两个心房的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;
}
Cell[]getEdges(列表协调列表)
{
int minX=coordinateList.get(0).getX;
int minY=coordinateList.get(0.getY);
int maxX=coordinateList.get(0.getX);
int maxY=coordinateList.get(0.getY);
单元格[]edgePair=新单元格[2];
For(单元格当前单元格:列表坐标列表)
{
if(currentCell.getX()maxY)
{
maxY=currentCell.getY();
}
}
edgePair[0]=新单元(minX,minY);
edgePair[1]=新单元(maxX,maxY);
回边;
}
这是2个循环的代码(与最大值相同,只需更改条件)

单元格getMinEdge(列表协调列表)
{
int minX=coordinateList.get(0).getX;
int minY=coordinateList.get(0.getY);
For(单元格当前单元格:列表坐标列表)
{

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

然而,我给你的建议是:

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

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

相反:

  • 以一种简单、自然的方式编写代码,然后对其进行基准测试,以使用实际输入来衡量应用程序的性能(或与实际输入的良好近似值)

  • 只有当性能测量结果表明代码需要更快运行时,才需要花时间尝试使代码更快运行

  • 一旦你决定需要优化,就用剖析器告诉你应该关注代码的哪些部分。不要依赖你的直觉,因为直觉往往是错误的


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

然而,我给你的建议是:

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

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

相反:

  • 以一种简单、自然的方式编写代码,然后对其进行基准测试,以使用实际输入来衡量应用程序的性能(或与实际输入的良好近似值)

  • 只有当性能测量结果表明代码需要更快运行时,才需要花时间尝试使代码更快运行

  • 一旦你决定需要优化,就用剖析器告诉你应该关注代码的哪些部分。不要依赖你的直觉,因为直觉往往是错误的


虽然我非常同意早期的微优化是不好的,但在这种情况下,需要考虑两种不同的算法。算法确实是决定性能好坏的因素,而不是像(++x)或(x++)或(x++=1)这样的问题“更有效”。 因此,问题为+1

(也就是说,最有可能的情况是,坐标列表中的项目太多,即使是不太优化的算法也不会以任何明显的方式延迟程序。)

概括一点,你是在问,当你需要以不同的方式减少一个大小为
n
的列表时,最好是单独减少
k
还是合并
k
的单一减少

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

我想指出的是,这只是一个很弱的建议。例如,如果您已经有了两种确定最小值和最大值的方法,那么可能就不值得编写第三种方法,它可以在一次运行中同时完成这两种操作。(除非这是绝对的性能杀手。)

但在这种情况下,您可以选择将所有内容组合到一个循环中,这也是最符合逻辑的,因此也是最容易理解的事情

如果我看到这样的代码

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

虽然我非常同意早期的微优化是不好的,但这是我的错误在这种情况下,需要考虑两种不同的算法,而算法确实是决定性能好坏的因素,而不是像(++x)或(x++)或(x++=1)这样的问题,哪一种更有效。 因此,问题为+1

(也就是说,最有可能的情况是,坐标列表中的项目太多,即使是不太优化的算法也不会以任何明显的方式延迟程序。)

概括一下,您会问,当您需要以
k
不同的方式缩减大小
n
列表时,是否最好单独缩减
k
for (X x: xs) { maxX = ...; }
for (X x: xs) { maxY = ...; }