I have recently begun to think about optimisation, now I know there are many books and articles but I have a particular scenario i'm interested in.
A.
for (i = 0; i < limit + 5; i++)
cout << test;
B.
limit2 = limit +5;
for (i = 0; i < limit2; i++)
cout << test;
What I want to 开发者_StackOverflowknow is would the second piece of code run faster because it only has to do the mathematical calculation once or is the calculation stored for the lifetime of the loop.
Assuming that the types are simple, as in int
etc., I'd be really surprised if any decent compiler didn't optimize both examples to the same code in a release build. A complex type might for instance require more horse-power in an overloaded operator++
.
Your compiler will probably generate the same machine-level instructions in both cases. Don't bother.
No difference at all.
And you shouldn't bother here, because cout << test
will use 99% of the time anyway.
Almost all the simple transformations you can do to the code, the compiler can do as well. Plus some!
Trust you compiler(tm)!
B is faster. However, it depends on a compiler and optimization level. Smart compiler with optimizations enabled will replace A with B.
You're focusing on an optimization that almost certainly doesn't matter, regardless of how it gets compiled. Focus on picking the right algorithms and design for the rest of your code. Profile to find out what's slow and optimize the areas that take the most time. Typically 10% of the code takes 90% of the time. You're currently thinking about a very small part of the 90% of the code that takes far less than 10% of the time in just about every possible scenario beyond having an empty loop block.
I'd say it makes no difference, as after constant-folding/constant-propagation (typical optimization techniques of the compiler) either limit + 5
(A) and limit2
(B) in the for-loop will be replaced by a constant value (provided limit can be resolved to a constant value).
So runtime should be the same, but compile-time could be slightly faster for A, as B needs more constant-propagation/constant-folding iterations. But thats just nitpicking and should be unnoticeable (unless you're compiling on a Zuse Z1)
My answer is :
It depends on the type of i
and limit
,since their types isn't mentioned in the question (as of now).
If they're built-in types (such as
int
,short
,long
,char
etc), then there wouldn't be much difference, not atleast noticeable difference for all practical purposes. That would also because most CPU cycles would be consumed bycout
alone. And the smart compilers would optimizeA
(and possiblyB
as well), emitting same code for both.If they're some user-defined types, and the type of
i
has overloadedoperator<
andoperator++
and type oflimit
overloadedoperator+
, then it all depends on how all these functions (operator overloads involved in the code) are defined. However, its more likely that thescenario B
would be faster sincelimit2 = limit +5;
would be calculated once.
Note: in the second case, the expression limit2 = limit +5
involves a function call which is basically this:
limit2 = limit.operator+(5);
The scenario B avoids the repepition of this function call if it stays outside of the for
loop.
Test it with something "more atomic" than cout, and with higher number of cycles. Anyway, these sources should generate the very same code.
There will likely be no difference.
One possible reason for the 2nd loop to be faster is if the compiler is able to infer that "limit2" doesn't have it's address taken anywhere, but can't infer that about "limit". If limit has it's address taken anywhere in the program then it's possible that the operator<< function you call could alter limit via that pointer and so it has to reload and recalculate the expression each time through the loop. Whereas if you copy limit +5 into a local variable the compiler can know there is no way for a legal program to have changed it.
精彩评论