rciafardone
rciafardone

Reputation: 125

Java efficiency comparison: 2 Loops with 2 conditions VS 1 Loop with 4 conditions

I have to search a list of objects to find the 2 lower and the 2 bigger values of a couple of atributes. In Java what is more efficient: To check the list once asking for the 4 values or do it twice to check for 2? in my experience 1 loop should be better, but there may be compilation optimization I may not know about.

This is the code for the single loop:

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;
}

this is the code for a 2 loops (Same for the max, just change condition)

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);
}

Thanks in advance for any suggestions.

Upvotes: 0

Views: 836

Answers (2)

Stephen C
Stephen C

Reputation: 718906

My intuition is that the version of the code with one loop should be faster than the version with two loops. (Assuming that you correct the syntax errors first!) I doubt that the optimizer would be able to combine the two loops into one, and performing the list iteration twice is going to take longer than performing it once.

However, my advice to you would be:

  • Don't rely too much on your (or my, or other peoples') intuition to tell you what is more efficient.

  • Don't spend too much time up-front thinking about what could / would / should be fastest.

Instead:

  • Write the code in a simple, natural way, and then benchmark it to measure your application's performance with real input. (Or a good approximation to real.)

  • Only spend time trying to make the code go faster if the performance measurements say that it needs to go faster.

  • Once you have decided that you need to optimize, use a profiler to tell you what parts of the code to focus your attention on. Don't rely on your intuition, because intuition is often wrong.

Upvotes: 4

Ingo
Ingo

Reputation: 36339

While I strongly agree that early micro-optimizations are bad, this is a case where two different algorithms are considered. And algorithms are indeed the things that make good or bad performance, as opposed to questions like which of (++x) or (x++) or (x+=1) is "more efficient". Hence, +1 for the question.

(That being said, most probably, you'll have only so many items in your coordinate list, that even the less optimal algorithm will not delay the program in any noticeable way.)

Generalizing a bit, you are asking if, when you need to reduce a list of size n in k different ways, it is better to do k separate reductions or a single reduction that combines the k ways.

The answer being that, if possible, one should strive to combine the k reductions into one. Or, in short: avoid repeated loops, if possible.

I want to point out that this is only a weak advice. If, for example, you had already 2 methods for determining the minima and maxima, it would be probably not worth writing a 3rd one that does it both in one run. (Except if it turns out that this is the absolute performance killer.)

But in this case, you have the choice and combining it all in one loop is also the most logical and hence best understandable thing to do.

If I would see code like this

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

I would ask myself on the 2nd line: "Why did he not do that in the first loop?" I would then check the previous code again to see if I have overlooked something that prevented computing the maxY right away. Since I wouldn't find anything, I would have to accept it somehow ... but still with the feel that I might have overlooked something.

Upvotes: 1

Related Questions