Calling a condition for a for loop (C ++)

Here's a simple question I've pondered for a long time: When I do a loop like this:

for (int i = 0; i < myVector.size() ; ++i) {
    // my loop
}

      

When the condition is i < myVector.size()

checked every time, should I store the size of the array inside a variable before the loop, to prevent calling on size () every iteration? Or is the compiler smart enough to do it itself?

mySize = myVector.size();   
for (int i = 0; i < mySize ; ++i) {
    // my loop
}

      

And I would extend the question to a more complex condition likei < myVector.front()/myVector.size()

Edit: I'm not using myVector inside a loop, it's just to give an end condition here. What about a more complex state?

+3


source to share


5 answers


The answer depends mainly on the content of your loop - it can change the vector during processing, thereby resizing it.

However, if the vector is just being scanned, you can safely store its size beforehand:

for (int i = 0, mySize = myVector.size(); i < mySize ; ++i) {
    // my loop
}

      



although in most classes functions like "get current size" are just built-in getters:

class XXX
{
public:
    int size() const { return mSize; }
    ....
private:
    int mSize;
    ....
};

      

so the compiler can easily reduce the call to just reading a variable int

, so length prefetching does not gain.

+2


source


I would say that

for (int i = 0; i < myVector.size() ; ++i) {
    // my loop
}

      

slightly safer than



mySize = myVector.size();   
for (int i = 0; i < mySize ; ++i) {
    // my loop
}

      

because the value myVector.size()

might change (as a result, for example, push_back(value)

inside a loop), so you might miss some of the elements.
If you are 100% sure that the value myVector.size()

will not change, then both will be the same.
However, the former is a little more flexible than the latter (another developer might not be aware that the loop repeats at a fixed size, and it might resize the array). Don't worry about the compiler, it's smarter than both of us.

+1


source


If you don't change anything in the vector (add / remove) during the while loop (this is the usual case), I would use a foreach loop

for (auto object : myVector)
{
  //here some code
}

      

or if you cannot use C ++ 11 I would use iterators

for (auto it = myVector.begin(); it != myVector.end(); ++it)
{
  //here some code
}

      

+1


source


Any clever compiler will probably optimize this. However, to be sure, I usually lay out my loops like this:

for (int i = myvector.size() -1; i >= 0; --i)
{

}

      

Several things are different:

  • Iteration is done the other way around. Although this shouldn't be a problem in most cases. If I prefer David Haim's method.

  • -I is used, not i. In theory, -i is faster, although it won't make any difference on most compilers.

If you are not interested in this index:

for (int i = myvector.size(); i > 0; --i)
{

}

      

There will also be an option. In general, I don't use it at all because it is a little more confusing than the first one. And you won't get any performance.

For type type std::vector

or std::list

iterator is the preferred method:

for (std::vector</*vectortype here*/>::iterator i = myVector.begin(); i != myVector.end(); ++i)
{

}

      

0


source


The overhead is very small. vector.size () does not recalculate anything, it just returns the value of the private size variable.

this is safer than pre-buffering the value because the vector's internal size variable changes when an element is popped or moved to / from the vector.

compilers can be written to optimize this if and only if, it can predict that the vector will not change in any way while the for loop is running. This is difficult to do if there are threads in there.

but if the thread is not running, it is very easy to optimize it.

0


source







All Articles