问题
I know, that everybody hates GOTO and nobody recommends it. But that's not the point. I just want to know, which code is the fastest:
the
goto
loopint i=3; loop: printf("something"); if(--i) goto loop;
the
while
loopint i=3; while(i--) { printf("something"); }
the
for
loopfor(int i=3; i; i--) { printf("something"); }
回答1:
Generally speaking, for
and while
loops get compiled to the same thing as goto
, so it usually won't make a difference. If you have your doubts, you can feel free to try all three and see which takes longer. Odds are you'll be unable to measure a difference, even if you loop a billion times.
If you look at this answer, you'll see that the compiler can generate exactly the same code for for
, while
, and goto
(only in this case there was no condition).
回答2:
Write short programs, then do this:
gcc -S -O2 p1.c
gcc -S -O2 p2.c
gcc -S -O2 p3.c
Analyze the output and see if there's any difference. Be sure to introduce some level of unpredictability such that the compiler doesn't optimize the program away to nothing.
Compilers do a great job of optimizing these trivial concerns. I'd suggest not to worry about it, and instead focus on what makes you more productive as a programmer.
Speed and efficiency is a great thing to worry about it, but 99% of the time that involves using proper data structures and algorithms... not worrying about whether a for
is faster than a while
or a goto
, etc.
回答3:
The only time I've seen the argument made for goto was in one of W. Richard Stevens' articles or books. His point was that in a very time-critical section of code (I believe his example was the network stack), having nested if/else blocks with related error-handling code could be redone using goto in a way that made a valuable difference.
Personally, I'm not good enough a programmer to argue with Stevens' work, so I won't try. goto can be useful for performance-related issues, but the limits of when that is so are fairly strict.
回答4:
It is probably both compiler, optimiser and architecture specific.
For example the code if(--i) goto loop;
is a conditional test followed by an unconditional branch. A compiler might simply generate corresponding code or it might be smart enough (though a compiler that did not have at least that much smarts may not be worth much), to generate a single conditional branch instruction. while(i--)
on the other hand is already a conditional branch at the source level, so translation to a conditional branch at the machine level may be more likley regardless of the sophistication of the compiler implementation or optimiser.
In the end, the difference is likley to be minute and only relevant if a great many iterations are required, and the way you should answer this question is to build the code for the specific target and compiler (and compiler settings) of interest, and either inspect the resultant machine level code or directly measure execution time.
In your examples the printf() in the loop will dominate any timing in any case; something simpler in the loop would make observations of the differences easier. I would suggest an empty loop, and then declaring i
volatile
to prevent the loop being optimised to nothing.
回答5:
As long as you're generating the same flow of control as a normal loop, pretty nearly any decent compiler can and will produce the same code whether you use for
, while
, etc. for it.
You can gain something from using goto
, but usually only if you're generating a flow of control that a normal loop simply can't (at least cleanly). A typical example is jumping into the middle of a loop to get a loop and a half construct, which most languages' normal loop statements (including C's) don't provide cleanly.
回答6:
There is should not be any significant difference between all the loops and the goto. Except the idea, that compiler more probably will not try to optimize the GOTO-things at all.
And there is not a lot of sense trying to optimize compiler-generated stuff in loops. It's more sense to optimize the code inside the loop, or reduce the number of iterations or so on.
回答7:
I think there will be some code after compiler under nornal condition.
In fact I think goto is very convenient sometimes, although it is hard to read.
回答8:
There are several niche verticals where goto is still commonly used as a standard practice, by some very very smart folks and there is no bias against goto in those settings. I used to work at a simulations focused company where all local fortran code had tons of gotos, the team was super smart, and the software worked near flawlessly.
So, we can leave the merit of goto aside, and if the question merely is to compare the loops, then we do so by profiling and/or comparing the assembly code. That said however, the question includes statements like printf etc. You can't really have a discussion about loop control logic optimization when doing that. Also, as others have pointed out, the given loops will all generate VERY similar machine codes.
All conditional branches are considered "taken" (true) in pipelined processor architectures anyway until decode phase, in addition to small loops being usually expanded to be loopless. So, in line with Harper's point above, it is unrealistic for goto to have any advantage whatsoever in simple loop control (just as for or while don't have an advantage over each other). GOTO makes sense usually in multiple nested loops or multiple nested ifs, when adding the additional condition checked by goto into EACH of the nested loops or nested ifs is suboptimal.
When optimizing a search kind of operation in a simple loop, using a sentinal is sometimes more effective than anything else. Essentially, by adding a dummy value at the end of the array, you can avoid checking for two conditions (end of array and value found) to be just one condition (value found), and that saves on cmp operations internally. I am unaware if compilers automatically do that or not.
来源:https://stackoverflow.com/questions/5366929/c-c-is-goto-faster-than-while-and-for