1

A question similar to this one has been asked before, it has no conclusive accepted answer.

Will this for loop call set.size() at every iteration of itself (set is a vector)?

for(int i = 0; i < set.size(); i++) 

Would the code bellow be any faster?

int size = set.size();  
for(int i = 0; i < size; i++)

Is the VS 2010 compiler smart enough to not let the program call .size() at every iteration?

Armend Veseli
  • 143
  • 2
  • 9
  • By that do you mean, did I try to accurately measure the code with a timer or did I try viewing the program with a dis-assembler? No, I don't know how to do either of those things. – Armend Veseli Oct 16 '14 at 03:15
  • "Is the compiler smart enough to not let the program call .size() at every iteration?" -- Suppose you were adding items to `set` within the loop ... would you want the compiler to optimize away the call? – Jim Balter Oct 16 '14 at 03:22
  • This is a question about specific compilers. If you had a specific compiler in mind then you could ask about that – M.M Oct 16 '14 at 03:22
  • This is with the VS 2010 compiler. – Armend Veseli Oct 16 '14 at 03:29

2 Answers2

3

In general modern optimizing compiler can do pretty powerful optimizations. It is very rarely worth it to do such optimizations yourself, usually you will just be getting in the compilers way. Before you even look at optimizing code you should profile your code to determine were the performance issue are.

A quick test with godbolt (see live code) using this code:

void function() {
  std::set<int> set ;
  set.insert( 10 ) ;
  set.insert( 20 ) ;

   for(int i = 0; i < set.size(); i++) 
   {
     printf( "%d\n", i ) ;
   }
}

Shows that it is directly accessing the count variable and not making a function call, the relevant assembly is:

movq    $0, 56(%rsp)    #, MEM[(struct _Rb_tree_impl *)&set]._M_node_count

and:

cmpq    %rbx, 56(%rsp)  # ivtmp.115, MEM[(long unsigned int *)&set + 40B]

So it would seem at least in this simple case the gcc optimizer was able to do the quick trick you wanted to do yourself. Although the generated code is different clang seems to be doing something similar as well.

Update

The question was updated to mention Visual Studio.

I don't know of an online tool to generate the Visual Studio assembly otherwise I would check that as well but I would not be surprised if Visual Studio also performs a similar optimization. As we can see the optimization is definitely possible. Once you generate the assembly in Visual Studio it is matter of determining whether a call to size() is made every iteration of the loop or not.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
3

A compiler might be smart enough to cache the result of set.size() if it could deduce that the result would not change throughout the lifetime of the loop. That's not a trivial optimization. If speed were critical I would not rely on the compiler making it. It would be safer, and clearer, to make the optimization explicit, so one looking at the code needn't wonder if there is a missed optimization opportunity.

And on the opposite side, if speed were not a concern (which it usually isn't), I would not bother with the microöptimization. Even if speed were a concern, you should still profile your code first and make sure this line of code actually is a bottleneck before applying any optimizations. That's a good rule of thumb in general.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578