1

Of the two following for loop implementations which should run faster or are they equal?

This one:

for(int i=0; i<objectPtr->bound; i++){

//do something that has no affect on objectPtr->bound

}

Or this one:

int myBound = objectPtr->bound;

for(int i=0; i<myBound; i++){
//do something that has no effect on objectPtr->bound or myBound
}

My hunch is the latter is faster but there could be some part of the compilation process that I don't understand that makes them equal in speed. I think the former will have to do an address resolution each loop cycle to determine if the value has changed.

Is there some c++ syntax that can be used to let the compiler know that the value/bound will not change. I know volatile lets the compiler know that the value will always have the possibility of changing so could I use const int for the objectPtr->bound variable to get the compiler to not always check its value each loop iteration?

aaron burns
  • 267
  • 4
  • 15
  • 1
    it depends on the "do something" code and on the compiler and the options, etc. if you want to help inform the compiler that the bound doesn't change, then declaring it as a non-`const` variable isn't particularly helpful. anyway, **MEASURE**. – Cheers and hth. - Alf Sep 22 '14 at 23:51
  • premature optimization – 2785528 Sep 22 '14 at 23:55
  • Use iterators, stl algorithms and lambdas. For a well-implemented data structure, you can't iterate any faster than the iterators. – Neil Kirk Sep 23 '14 at 00:01
  • Definitely NOT a premature optimization problem. This is for eventual use in an embedded device with a hyper spectral camera. – aaron burns Sep 23 '14 at 00:12
  • 1
    @aaronburns: It is a premature optimization problem because you don't seem to know how to test it. What is going on in that loop? Does it take a long time compared to anything else, making the lookup time reside in the noise? Does your compiler generate the same code for both versions? It's premature because you've shown no problem nor have you performed even the most basic of investigations. It's also premature in the sense that you don't seem to know how your code works at a basic level (which is fine, everyone starts somewhere, but this question is a bit naive). – Ed S. Sep 23 '14 at 00:16
  • @aaronburns My apologies for, perhaps, excessive assumptions on my part. I did not mean to insult you. What I was noting that you mentioned a "hunch" but gave no indication that you had tried to evaluate/contrast/compare your two choices (perhaps by testing, perhaps by inspecting assembly code, perhaps by attaching hw monitoring equipment). Also, there are other choices you might consider (besides the for loop, I mean). – 2785528 Sep 25 '14 at 20:05
  • Something as common as this I would think would have some documentation already. I have some other widgets to create so was trying to minimize the effort on this task. Also I did not see any questions like this on SO so thought that fleshing it out or getting an answer would serve the whole community. – aaron burns Sep 25 '14 at 22:49

1 Answers1

0

The compiler might see that the value of objectPtr->bound doesn't change between iterations. In this case, it will automatically extract it into a variable to avoid repeated lookups.

There is no way to explicitly tell the compiler that the value of an expression doesn't change. If the compiler can't detect it itself, you can copy the value into a variable as you did.

Declaring local variables as const is not necessary. The compiler can see that you don't assign to the variable in a loop and deduce that its value doesn't change.

abacabadabacaba
  • 2,662
  • 1
  • 13
  • 18
  • 1
    The assumption "The compiler can see" contradicts, to some extent, the assumption/context of a compiler that's too dumb the note that the bound doesn't change. With a `const` (a variable that's *originally* `const`) you have UB if it does change. That allows optimization of the loop without further data flow analysis (in C++ UB is the big optimization enabler). – Cheers and hth. - Alf Sep 23 '14 at 00:03
  • @Cheersandhth.-Alf AFAIK, it's UB only if the variable is static. – abacabadabacaba Sep 23 '14 at 00:05
  • @aaronburns UB means Undefined Behavior. Basically, if something is UB, the compiler can assume that it doesn't happen. – abacabadabacaba Sep 23 '14 at 00:16
  • 1
    @abacabadabacaba: C++11 §7.1.6.1/4 “Except that any class member declared `mutable` (7.1.1) can be modified, any attempt to modify a `const` object during its lifetime (3.8) results in undefined behavior”. Nothing about static there. The non-normative example goes to lengths to show that the UB also covers dynamically allocated object, when that object is originally `const`, so unless you have an argument that indicates that dynamically allocated objects are static, I'd say your opinion rests on shaky foundation. – Cheers and hth. - Alf Sep 23 '14 at 02:22
  • @Cheersandhth.-Alf You are right. Still, detecting that a local variable is never assigned and that its address is never taken is what most compilers can do, and in this case modifying this variable by any means (like through "guessing" its address) is UB. – abacabadabacaba Sep 23 '14 at 03:15