Reputation: 3045
Which is better for performance? This may not be consistent with other programming languages, so if they are different, or if you can answer my question with your knowledge in a particular language, please explain.
I will be using c++ as an example, but I would like to know how it works in java, c, or any other mainstream languages.
int x = 0;
while (x < 10) {
cout << x << "\n ";
x++;
}
VS
for ( int x = 1; x < 10; x++)
cout << x << "\n ";
Which one performs better? If it is the for loop, then lets say that there was an integer already declared that we could use in the while loop increment, that we didn't need to create just for the while loop?
example:
int age = 17; //this was made for something else in the code, not a while loop. But fortunately for us, our while loop just so happened to need the number 17.
while (age < 25) {
cout << age << "\n ";
age++;
}
Would this instance make the while loop a better choice than creating a for loop? And I have seen questions somewhat similar to this, but I do not believe that this is a duplicate, or any of the answers on those other questions answered my question.
I want an explanation on this question, explaining if it is compiler specific, how it works, or whatever is a good answer to this question.
Upvotes: 0
Views: 3064
Reputation: 1275
It won't make any difference with compiler optimization!
My 2cts, when it deals about loop implementation choice, it's important to use the one which suits the algorithm logic. It's easier to read the code.
Upvotes: 1
Reputation: 53027
The example you posted actually has different behavior for while
and for
.
This:
for (int x = 0; x < 100; ++x) {
foo y;
y.bar(x);
}
Is equivalent to this:
{ // extra blocks needed
int x = 0;
while (x < 100) {
{
foo y;
y.bar(x);
}
++x;
}
}
And you can expect the performance to be identical. Without the extra braces the meaning is different, and so the assembly generated may be different.
While the differences between the two is nonexistent on a modern compiler, for
may optimize better as states its behavior more explicitly.
Upvotes: 2
Reputation: 78903
Your question as you give it is ill posed. The IO that you have inside the loops dominates all that the loop handling statements ever could add by at least one order of magnitude. My bet would even be that you can't measure any significant difference since it would not be distinguishable from the noise (in terms of measurement) that the IO produces.
The thing would only matter, if the code inside the loop would be really fast. Here fast meaning not even to have a memory read instruction, since then already CPU memory bandwidth would dominate, again.
So if you are really curious, and you seem to be, read the assembler and look at the code. If you only have two small functions with just each type of loop, the output is not so difficult to read, really, don't be scared. I'd suggest to do it with C, though, this is probably closest to the assembly and easiest for you to identify the parts.
You didn't tell us on what system/compiler you are. With gcc the options would be -S -O3 -march=native
to have it produce a .s
file.
Upvotes: 1
Reputation: 612854
I find it hard to imagine situations where the code samples you give would have different performance characteristics.
I do have a mild curiosity for you though. In Pascal like languages (e.g. Delphi) the loop limits are evaluated only once. This differs from the C like languages where the loop limits are evaluated each iteration. This can have performance implications but of course its trivial to write performant code in C like languages by introducing a local outside the loop.
For example:
Delphi
for i := 0 to List.Count-1 do
DoStuff(List[i]);
List.Count
is only evaluated once.
C++
for (int i=0; i<List.getCount(); i++)
DoStuff(List.getItem(i));
Here, List.getCount()
is called every time around the loop.
If it transpires that evaluating the loop limits is expensive then this difference can be relevant. Naturally it is trivial to evaluate List.getCount()
outside the loop and store the result in a local variable.
Having compared the for
loops of Pascal and C/C++ I would say that the Pascal version is very simplistic in comparison. This is not necessarily a bad thing because for more complex there is always while
available.
Upvotes: 2
Reputation: 57774
On certain CPU architectures, the characteristics of the loop may provide opportunities for more optimization than the choice of for
versus while
.
In particular, FORTRAN
and Pascal
recommended a constant (rather than a variable) for the number of loop iterations which some CPUs can optimize. For example, on a Cyber (a 1970s Iron Dinosaur mainframe), a 15-bit register holds the for
loop index which can easily be compared. A while
instead uses one or two of the harder-to-access 60-bit registers. Also, a Cyber branch instruction is considerably more expensive than the loop housekeeping, or possibly the loop content. In such cases, a high level of optimization might unroll the loop to avoid all the overhead.
However, modern code generators don't work like they used to: source code is turned into an intermediate parse structure which abstracts such choices away. In short, for
versus while
makes no difference.
Upvotes: 3
Reputation: 889
I would suggest that you write a small example and time the difference. Then select whatever solution you find to be the quickest.
Upvotes: 1
Reputation: 673
I think compilers are optimized enough these days so it really doesn't makes a difference if you use a for loop or a while loop.
Upvotes: 1
Reputation: 887305
All sensible compilers should compile equivalent loops to identical assembly / IL code involving branches and jumps. (at least with optimizations enabled)
Upvotes: 4
Reputation: 838086
It is compiler specific, but I would imagine that in nearly all cases the performance will be the same for both approaches.
To be sure for a specific situation you should measure the performance, although before you spend many hours micro-optimizing code like this you should first be sure that this is in fact the bottleneck in your application (probably it isn't).
Your second example could be writen as a for
loop with no initialization expression.
int age = 17; // This was made for something else in the code
for (; age < 25; age++) {
cout << age << endl;
}
Upvotes: 1