We often loop over arrays starting with the last elment in this way:
static const char* pszStrings[] = { ... }
for (size_t i = _countof(pszStrings); i--;)
use(pszStrings[i]);
My question is, if the new range based for loop is as efficient and so to be used:
static const char* pszStrings[] = { ... }
for (auto string : pszStrings)
use(string);
Additionally …
Since I'm not able to take a look at the generated code, and even if, I don't know, if I'd be able to make the right conclusions, I'll be glad for not too scientific answers!
The compiler can make a lot of assumption about the iterated collection in the new range for-loop, that in the previously written for-loop. Example:
In C++98 days normally one write:
for (std::vector<int>::const_iterator it = v.begin(), it_end = v.end();
it != it_end; ++it) {
// code ..
}
The it_end was used because in a lot of case the compiler could not be sure that the collection would not change size inside the for-loop (and .end() could change). If you write:
for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
// code ..
}
The compiler can generate a call to the .end() function for every execution of the loop.
The range for-loop is as efficient (some times more efficient) that the old for-loop.
Some examples:
If you have a loop iterating a std::vector by index: for (int i = 0; i < v.size(); ++i) this loop would need to index the vector to use the element (v[i]) most sure not a noticeable wait, but when vector are really big, in a tight loop could be notice.
This kind of loop would improve when updated to range for-loop.
The first loop in the answer most probably would not improve in performance, but would in clarity, the reader of the code would know that the code is meant to iterate all the collection and not skip some elements (in the old way, you could recognize the for-each pattern in the for-loop, but it's tedious and could lead to erroneous conclusions (probably in the body are modifying the index or the iterator) about the code if not careful.
Related
Given
std::vector<double> a;
std::vector<int> ind;
where ind is 1sorted in ascending order.
I want to do the equivalent of the following:
for (auto it=ind.rbegin();it!=ind.rend();it++) a.erase(a.begin() + *it);
I came up with this:
for (auto it=ind.begin();it!=ind.end();it++)
a[*it] = std::numeric_limits<double>::max();
std::erase(std::remove(a.begin(),a.end(),std::numeric_limits<double>::max()),a.end());
This is very fast, but it doesn't feel right to use the std::numeric_limits::max() as a flag in this context.
Of course feelings shouldn't play too much into the equation ... clearly comparing the doubles within the std::remove is safe, and the limit will never occur in practice in this vector in a working application, so it should be ok, no?
Any thoughts on this?
1) Ref comment by the OP. – Alf
Let's look at your "baseline" code, that you say you want to do the "equivalent" of:
std::vector<double> a;
std::vector<int> ind;
for (auto it = ind.rbegin(); it != ind.rend(); it++)
a.erase(a.begin() + *it);
What we gather from this is that ind is a vector of indexes in a which should be removed, and that they are sorted ascending. Those indexes must be removed from a. I assume your goal is to do this efficiently in terms of space and time.
If you think about it in terms of the minimum number of operations required, you have to shift many/most/all of the elements in a in order to erase the ones indicated by ind. You don't want to erase() several times because this means shifting some elements more than once. One optimal solution (in the general case, not imposing special requirements on the values in a) looks like this:
size_t slow = 0; // where we are currently copying "to"
std::vector<int> inditer = ind.begin();
for (size_t fast = 0; fast != a.size(); ++fast) {
if (inditer != ind.end() && *inditer == fast) {
// "remove" this element by ignoring it
++inditer;
} else {
a[slow] = a[fast];
++slow;
}
}
a.resize(slow);
Now, you could probably reformulate this using STL algorithms and a custom predicate (functor) which remembers its "current" position in ind, but it will not be much less code and it might be harder to understand.
I would like to traverse a map in C++ with iterators but not all the way to the end.
The problem is that even if we can do basic operations with iterators, we cannot add or compare iterators with integers.
How can I write the following instructions? (final is a map; window, an integer)
for (it=final.begin(); it!=final.end()-window; it++)
You cannot subtract from a map iterator directly, because it is an expensive operation (in practice doing --iter the required number of times). If you really want to do it anyway, you can use the standard library function 'advance'.
map<...>::iterator end = final.end();
std::advance(end, -window);
That will give you the end of your window.
std::map<T1, T2>::iterator it = final.begin();
for (int i = 0; i < final.size()-window; ++i, ++it)
{
// TODO: add your normal loop body
}
Replace T1 and T2 with the actual types of the keys and values of the map.
Why don't you make 'it' an iterator as well ?
See the example here : http://www.cplusplus.com/reference/stl/map/begin/
Another solution:
size_t count=final.size();
size_t processCount=(window<count?count-window:0);
for (it=final.begin(); processCount && it!=final.end(); ++it, --processCount)
{
// loop body
}
This one is a bit safer:
It takes care of the case when your map is actually smaller than the value of window.
It will process at most processCount elements, even if you change the size of your map inside your loop (e.g. add new elements)
According to STL, size() can take O(n) time to compute, although usual implementations can do this in O(1). To be on the safe side, it is better not to call size() many times, if it is not necessary.
'end()' on the other hand has amortized constant time, so it should be OK to have it in the for-loop condition
++it may be faster than it++. The post-increment operator creates a temporary object, while the other - does not. When the variable is a simple integral type, compiler can optimise it out, but with iterators it is not always the case.
I'm working on a aplication where I draw a couple of images, like this:
void TimeSlice::draw(float fX, float fY) {
list<TimeSliceLevel*>::iterator it = levels.begin();
float level_x = x;
float level_y = y;
while(it != levels.end()) {
(*it)->draw(level_x,level_y);
level_y += (*it)->height;
++it;
}
}
Though this is a bit incorrect. I need to position the TimeSliceLevel* on a X.. When I've
got a for(int i = 0; i < slices.size(); ++i) loop, I can use x = i * width. Though I'm using an iterator as I've been told many times that's good programming :> and I'm wondering if the iterator has a "index" number of something which I can use to calculate the new X position? (So it's more a question about using iterators)
Kind regards,
Pollux
They don't, as iterators can be used for other purposes besides looping from the beginning to the end of an ordered, indexed list. You'll need to keep track of an index separately and increment it every pass:
list<TimeSliceLevel*>::iterator it;
int index;
for(it = levels.begin(), index = 0; it != levels.end(); ++it, ++index) {
...
}
No, it doesn't. If you need an integer index, use a for-loop. Despite what some iterator extremists would have you believe, for-loops still have their place in C++ code.
It is possible to go from iterator -> index. There are at least two ways:
Use - for Random access iterators (i.e. i - container.begin())
Use std::distance (i.e. std::distance(containter.begin(), i)). This is a more "generic" solution and will perform identically in the random access iterator case to - thanks to specialization, but will have a terrible performance impact otherwise
However, I would not recommend either of them, as it obfuscates the code (and can be unperformant). Instead as others have said, use an additional counter. There is nothing "wrong" with using indexes when needed, rather preferring iterators is meant to be a guideline to help in writing "generic" code, as then you can apply the algorithm to a different container, or a sub set of the container, etc.
For some iterator types, simply subtract the current iterator from the initial iterator:
index = it - levels.begin()
Since this does not work for std::list iterators, just track the index explicitly with a variable, as mentioned in the above answers. The benefit of using the iterator and the container is not lost. You're adding a requirement that the container doesn't provide.
You would have to write something like
size_t index = 0;
for (list<...>::const_iterator it = y.begin(); it != y.end(); ++it) {
// Do your actions based on `index`
++index;
}
and, well, this is sometimes suitable.
On the other hand, you could refactor (replan) your application so that your actual drawing loop doesn't have to make all those x += something, y += something2, ..., but rather act the following way:
foreach (Level* level, list) {
level->draw(backend);
}
It could sometimes be tricky, but to my mind this approach could save you a lot of time if your application grows to something "big".
You CAN BUT ONLY for random-access iterator. If it's a random access iterator you can subtract your iterator from the begin iterator to obtain the index (without keeping a separate int index variable).
for (vector<int>::const_iterator cit = v.begin(); cit != v.end(); ++cit)
{
cout << "This is element no: " << cit - v.begin() << endl;
}
In your example unfortunately you won't be able to do it, because you are using std::list, which is only a bidirectional iterator. Use std::vector and you can do it like my example.
Which of the following is better and why? (Particular to c++)
a.
int i(0), iMax(vec.length());//vec is a container, say std::vector
for(;i < iMax; ++i)
{
//loop body
}
b.
for( int i(0);i < vec.length(); ++i)
{
//loop body
}
I have seen advice for (a) because of the call to length function. This is bothering me. Doesn't any modern compiler do the optimization of (b) to be similar to (a)?
Example (b) has a different meaning to example (a), and the compiler must interpret it as you write it.
If, (for some made-up reason that I can't think of), I wrote code to do this:
for( int i(0);i < vec.length(); ++i)
{
if(i%4 == 0)
vec.push_back(Widget());
}
I really would not have wanted the compiler to optimise out each call to vec.length(), because I would get different results.
I like:
for (int i = 0, e = vec.length(); i != e; ++i)
Of course, this would also work for iterators:
for (vector<int>::const_iterator i = v.begin(), e = v.end(); i != e; ++i)
I like this because it's both efficient (calling end() just once), and also relatively succinct (only having to type vector<int>::const_iterator once).
I'm surprised nobody has said the obvious:
In 99.99% of cases, it doesn't matter.
Unless you are using some container where calculating size() is an expensive operation, it is unfathomable that your program will go even a few nanoseconds slower. I would say stick with the more readable until you profile your code and find that size() is a bottleneck.
There are two issues to debate here:
The variable scope
The end condition re-evaluation
Variable scope
Normally, you wouldn't need the loop variable to be visible outside of the loop. That's why you can declare it inside the for construct.
End condition re-evaluation
Andrew Shepherd stated it nicely: it means something different to put a function call inside the end condition:
for( vector<...>::size_type i = 0; i < v.size(); ++i ) { // vector size may grow.
if( ... ) v.push_back( i ); // contrived, but possible
}
// note: this code may be replaced by a std::for_each construct, the previous can't.
for( vector<...>::size_type i = 0, elements = v.size(); i != elements; ++i ) {
}
Why is it bodering you?
Those two alternatives dont see to be doing the same. One is doing a fixed number of iterations, while the other is dependant on the loops body.
Another alternative colud be
for (vector<T>::iterator it=vec.begin();it!=vec.end();it++){
//loop body
}
Unless you need the loop variable outside the loop, the second approach is preferable.
Iterators will actually give you as good or better performance. (There was a big comparison thread on comp.lang.c++.moderated a few years back).
Also, I would use
int i = 0;
Rather than the constructor like syntax you're using. While valid, it's not idiomatic.
Somewhat unrelated:
Warning: Comparison between signed and unsigned integer.
The correct type for array and vector indices is size_t.
Strictly speaking, in C++ it is even std::vector<>::size_type.
Amazing how many C/C++ developers still get this one wrong.
Let's see on the generated code (I use MSVS 2008 with full optimization).
a.
int i(0), iMax(vec.size());//vec is a container, say std::vector
for(;i < iMax; ++i)
{
//loop body
}
The for loop produces 2 assembler instructions.
b.
for( int i(0);i < vec.size(); ++i)
{
//loop body
}
The for loop produces 8 assembler instructions. vec.size() is successfully inlined.
c.
for (std::vector<int>::const_iterator i = vec.begin(), e = vec.end(); i != e; ++i)
{
//loop body
}
The for loop produces 15 assembler instructions (everything is inlined, but the code has a lot of jumps)
So, if your application is performance critical use a). Otherwise b) or c).
It should be noted that the iterator examples:
for (vector<T>::iterator it=vec.begin();it!=vec.end();it++){
//loop body
}
could invalidate the loop iterator 'it' should the loop body cause the vector to reallocate. Thus it is not equivalent to
for (int i=0;i<vec.size();++i){
//loop body
}
where loop body adds elements to vec.
Simple question: are you modifying vec in the loop?
answer to this question will lead to your answer too.
jrh
It's very hard for a compiler to hoist the vec.length() call in the safe knowledge that it's constant, unless it gets inlined (which hopefully it often will!). But at least i should definitely be declared in the second style "b", even if the length call needs to be "manually" hoisted out of the loop!
This one is preferable:
typedef vector<int> container; // not really required,
// you could just use vector<int> in for loop
for (container::const_iterator i = v.begin(); i != v.end(); ++i)
{
// do something with (*i)
}
I can tell right away that the vector
is not being updated
anyone can tell what is happening
here
I know how many loops
v.end() returns pointer one past the
last element so there's no overhead
of checking size
easy to update for different
containers or value types
(b) won't calculate/call the function each time.
-- begin excerpt ----
Loop Invariant Code Motion:
GCC includes loop invariant code motion as part of its loop optimizer as well as in its partial redundancy elimination pass. This optimization removes instructions from loops, which compute a value which does not change throughout the lifetime of a loop.
--- end excerpt --
More optimizations for gcc:
https://www.in.redhat.com/software/gnupro/technical/gnupro_gcc.php3
Why not sidestep the issue entirely with BOOST_FOREACH
#include <boost/foreach.hpp>
std::vector<double> vec;
//...
BOOST_FOREACH( double &d, vec)
{
std::cout << d;
}
What are the Advantages/Drawbacks of these two ways of iterating through a container / which one do you prefer and why:
for (MyClass::iterator i = m.begin(), e = m.end() ; i != e ; i++)
{
// ...
}
or
for (MyClass::iterator i = m.begin() ; i != m.end() ; i++)
{
// ...
}
Subsidiary question: i++ or ++i? Why?
If the iterator is non-trivial (ie. not a pointer), ++i is definitely faster as it doesn't involves a copy to a temporary, which may or may not be optimized out.
The first form is a little faster but could be wrong if you erase or insert things in the loop.
For simple iteration over a container I use
#define foreach BOOST_FOREACH // in some header
foreach(MyType &element, any_container) {
// deal with element
}
most of the time for succinctness and clarity.
Unless you have optimizations turned off, both are equivalent. As for i++ or ++i, ++i is more efficient because it does not involve a temporary value.
For normal stl iterators there's not a great deal of difference however if you collections are complex and asking for end is expensive then only asking for the end once may be faster.
Similarly for ++i vs i++, ++i can be a more expensive operation when the iterator is a complex class (rather than just a pointer as in the stl iterators) with i++ what's happening is that it's incrementing the iterator but returning a copy of the iterator in it's previous state. for ++i it's returning the iterator in it's current state so can just return a reference to itself.
It's usually best to only optimize your code when your profiler identifies that there's a problem there - it's better to keep the code as easily readable as possible.
I always do the second one actually, although I do worry sometimes if multiple calls to end slows things down at all. I was under the impression this would be optimised, but don't know that for sure.
And ++i definitely. It's never slower than i++, if anything it's faster.
The first one is faster because end() isn't called on every iteration. And no, the optimizer can't easily cache that for you, because it doesn't know whether the size of the container has changed in this iteration (and hence the end moved). This also applies to a const container due to the aliasing problem.
i++ returns a copy of i, then increments. ++i increments, then returns the incremented value. Hence, when you are discarding the return value, use ++i because it needs to do less work (no copying). The optimizer is quite likely to fix an inlined i++ call so it's as fast as ++i but don't rely on that.
Me? I use
for(int i = 0; i < m.size(); i++) {
// ... do something with m[i]
}
Because it's the shortest and most clear. Why int and not MyClass::size_type? Because it's simpler and I have never had to worry about the edge cases so far. Why i++? Because for basic types it's always optimized into ++i, and it's less confusing for coworkers. As a bonus, I can use i as a numeric value as well. With an iterator, I'd have to keep a separate counter, or use std::distance.
obecalp points out that this doesn't work with half of the standard containers, like list and map. Indeed those require using a proper iterator. Relatedly, you should always use an iterator when writing generic code.
The C++ "for every element in container" loop is the most efficient where the context doesn't call for iterative logic.
for(Item& i : Container)
{
dosomething(i);
}
or
for(const Item& i : Container)
{
dosomething(i);
}
Boost.Foreach introduces a nice way:
#define foreach BOOST_FOREACH
// ...
Container<Item> container;
// ...
foreach (Item item, container) {
// do some stuff with the item
}