开发者

Are container.end() and container.size() inlined?

I typically get into the discussion with others and I'm not able to confirm the behavior - if the container.end() and container.size() functions are inlined. For e.g. if we have a for loop as such:

for (vector<int>::iterator it=v.begin(); it!=v.end(); ++it) {
   //...
} 

for (size_t k=0; k < v.size(); ++k) {
   //...
}

In the above cases, will the v.end() and v.size() functions be called repeatedly or

  1. will compiler inline thes开发者_如何学运维e functions
  2. Will temporary variable be created by compiler
  3. Does optimization options O1..3 impact the behavior in g++?


All template functions are by definition inline functions. The compiler may choose to make them callable functions, especially if it's a debug mode compilation, but the most likely outcome is for the code to be inlined.

It's possible but unlikely that a temporary variable will be automatically created. How does the compiler determine if the v.end() or v.size() return values will be impacted by the code within the loop? I suspect most don't bother, although I don't have any evidence either way.


Even if the functions are inlined, you cannot count on the compiler to correctly optimize the loop if the nested code is sufficiently large/complex. This is because semantically, you probably don't expect the end() value to change on every iteration of the loop, so it should only be computed once and. However, the compiler may not be able to make that guarantee based on aliasing considerations and other "give-up" conditions in the optimizer. If--like other posters have answered--you pre-calculate end() and store it in a variable, the compiler is less likely to get confused.

For example:

typedef std::vector<int> intvec;
intvec v = external_function();
for (intvec::const_iterator vi = v.begin(); vi != v.end(); ++vi) {
    call_external_function(v, *vi);
}

From the compiler's perspective, call_external_function() is liable to change the size of the vector. If you know it cannot happen, you should be telling the compiler so:

for (intvec::const_iterator vi = v.begin(), ve = v.end(); vi != ve; ++vi) {
    call_external_function(v, *vi);
}


Even though template functions are inlined, it's difficult to say that compiler will provide the same degree of optimization we need. One can use below techniques.

Store v.end() in a temporary vEnd:

for(vector<TYPE>::iterator it = v.begin(), vEnd = v.end(); it != vEnd; it++) {}

Execute the loop in reverse:

for (size_t k = v.size() - 1; k != (size_t)(-1) ; --k) { }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜