Reputation: 2893
#include <vector>
#include <iostream>
class Range {
typedef typename std::vector<int> Vec;
typedef typename Vec::iterator Iterator;
public:
Range(Vec& vec, const int start_id, const int size)
: vec_{vec},
it_begin_{vec_.begin() + start_id},
it_end_ {vec_.begin() + start_id + size}
{}
Iterator& begin() {return it_begin_;}
Iterator& end() {return it_end_;}
private:
Vec& vec_;
Iterator it_begin_;
Iterator it_end_;
};
int main()
{
std::vector<int> a;
a.resize(100);
Range range(a,0,10);
for (auto it = range.begin(); it != range.end(); ++it) { // Line A
std::cout << it - range.begin() << "\n"; // Line B
}
}
Suppose I use optimization (like g++ -Ofast
).
In Line A, would the program call range.end()
for many times, instead of saving the value of range.end() and compare that value with it in every iteration of the loop?
In Line B, would the program call range.begin()
for many times, instead of saving the value of range.begin()
for the whole loop and then subtract that value from it in every iteration of the loop?
Upvotes: 4
Views: 493
Reputation: 62583
It is hard to predict what optimizer would and would not do on a given optimization level. While this particular transformation is trivial, and usually done whenever inlining is allowed, it is not guaranteed.
When in doubt, I'd follow the old Russian saying, loosely translated as 'Have faith in the optimizer, but do not be a dummy yourself!'. So I would use a const variable to store the result of the call. It will first and foremost make the code more readable, and as a nice side effect it might help some paradoxical optimizers. And a good optimizer will eliminate the variable anyways.
Upvotes: 4
Reputation: 9786
The access of .end()
member has a constant complexity, it is read once and it is used as the limit in the loop. You can check this example for map
container, but it applies for others as well.
Upvotes: 1
Reputation: 30831
In your code, the optimizer can see the implementations of begin()
and end()
. It can inline them, and hoist invariants out of the loop.
The answer would likely be different if begin()
and end()
were in a different translation unit than the main()
, as link-time is usually too late for such optimizations.
Upvotes: 4