C ++ for loop optimization

I have the following looking code in VC ++:

for (int i = (a - 1) * b; i < a * b && i < someObject->someFunction(); i++) { // ... } 

As far as I know, compilers optimize all these arithmetic operations, and they will not be performed in every cycle, but I'm not sure if they can say that the function above also returns the same value every time, t needs to be called every time.

Is it better to store all calculations in variables or just rely on compiler optimizations to have more readable code?

 int start = (a - 1) * b; int expra = a * b; int exprb = someObject->someFunction(); for (int i = startl i < expra && i < exprb; i++) { // ... } 
+6
c ++ optimization visual-c ++
source share
6 answers

If a function is inside the same compilation unit as the caller, the compiler can often output some facts about it - for example, that its output cannot change for subsequent calls. In general, however, this is not so.

In your example, assigning variables to these simple arithmetic expressions does not change anything with respect to the generated object code and, in my opinion, makes the code less readable. If you do not have a bunch of long expressions that cannot reasonably be placed in one or two lines, you should avoid using temporary variables - if not for any other reason, then simply to reduce pollution of the namespace.

The use of temporary variables implies significant administrator overhead for the programmer to keep them separate and avoid unintended side effects. It also simplifies the reuse of code snippets.

On the other hand, assigning the result of a function to a variable can help the compiler optimize your code better by explicitly avoiding multiple function calls.

Personally, I would go with this:

 int expr = someObject->someFunction(); for (int i = (a - 1) * b; i < a * b && i < expr; i++) { // ... } 
+5
source share

Short answer: it depends. If the compiler can output someObject->someFunction() each time and cache the result each time, as soon as they produce the same effects, this is allowed (but not guaranteed). Regardless of whether this static analysis is possible, it depends on your program: in particular, what is the static type someObject and what is its dynamic type, as well as what someFunction() really does, be it virtual , etc. on the.

In general, if you need to do this only once, write your code so that it can be executed only once, bypassing the need to worry about what the compiler can do:

 int start = (a - 1) * b; int expra = a * b; int exprb = someObject->someFunction(); for (int i = start; i < expra && i < exprb; i++) // ... 

Or, if you are brief:

 for (int i = (a - 1) * b, expra = a * b, exprb = someObject->someFunction(); i < expra && i < exprb; i++) // ... 
+7
source share

From my experience, the VC ++ compiler will not optimize a function call if it cannot see the implementation of the function at the time the calling code is compiled. So moving the call outside the loop is a good idea.

+6
source share

The compiler cannot make any assumptions about whether your function will return the same value at any given time. Imagine your object is a socket, how could the compiler know what its output would be?

In addition, the optimization that the compiler can create in such loops depends heavily on whether a and b are declared as const or not, and whether they are local. With advanced optimization schemes, it can be established that a and b do not change either in the loop or in your function (again, you can assume that your object has some reference to them).

Well, in short: switching to the second version of your code!

+1
source share

It is very likely that the compiler will call the function every time.

If you're interested in code readability, how about using:

 int maxindex = min (expra, exprb); for (i=start; i<maxindex; i++) 

IMHO, long lines do not improve readability.

Writing short lines and following a few steps to get the result does not affect performance, which is why we use compilers.

0
source share

Effectively, you can ask if the compiler will inline someFunction () and see if someObject is the same instance in every loop, and if it does, it will potentially “cache” the return value and not continue to overestimate his.

Most of this can depend on what optimization options you use with VC ++, as well as with any other compiler, although I'm not sure that VC ++ gives you as many flags as gnu.

It often seems unbelievable to me that programmers rely on compilers to optimize things that they can easily optimize. Just move the expression to the first section of the for loop if you know what it will evaluate each time:

Just do it and don't rely on the compiler:

 for (int i = (a - 1) * b, iMax = someObject->someFunction(); i < a * b && i < iMax; ++i) { // body } 
0
source share

All Articles