views:

3111

answers:

10

Which is better( or faster) c++ for loop or the foreach operator provided by Qt? For example,the following condition QList listofstrings; Which is better?

foreach(QString str, listofstrings)
{
  //code
}

or

int count = listofstrings.count();
QString str = QString();
for(int i=0;i<count;i++)
{
  str = listofstrings.at(i);
  //code
}
+35  A: 

It really doesn't matter. Trust me.

The large number of questions on SO regarding whether this method or that method is faster, belie the fact that, in the vast majority of cases, code spends most of its time sitting around waiting for users to do something.

If you're really concerned, profile it for yourself.

But I think you'll most likely find that only in the most intense data-processing-heavy work does this question matter. The difference may well be only a couple of seconds and even then, only when processing huge numbers of elements.

Get your code working first. Then get it working fast (and only if you find an actual performance issue).

Time spent optimising before you've finished the functionality and can properly profile, is mostly wasted time.

paxdiablo
The number passed the joke stage long ago. We should write an answer bot that looks for "which is faster" and auto-replies: profile it
JaredPar
See http://stackoverflow.com/questions/771092/is-method-a-faster-than-method-b : let's see if it survives :-)
paxdiablo
Not that it really applies so much to the simple example, but what I like to say is, "Incorrect code is as unoptimized as you can get".
Michael Burr
Ooh, that's a good one, @MB, I'll add that to my list of mantras.
paxdiablo
@Michael that went onto my list as well.
JaredPar
Most code in a program is only executed a limited number of times, and humans are bad at predicting which code (and humans who think they're good at it are also bad at it). Micro-optimizing code that isn't executed much is completely pointless. I'd never micro-optimize without knowing there as a performance issue, or without profiling the code.
David Thornley
@paxdiablo: “mostly wasted”? Damn close to all. (Very occasionally you know early on that a particular code path is going to be hot and can take special care with it, but it's ever so rare.)
Donal Fellows
@JaredPar: a bot seems a bit over the top, but a suggestion when creating the question would be indeed nice. We have the "seems subjective - probably will be closed" one, adding a few more should not be a problem.
PeterK
+1  A: 

The foreach from Qt has a clearer syntax for the for loop IMHO, so it's better in that sense. Performance wise I doubt there's anything in it.

You could consider using the BOOST_FOREACH instead, as it is a well thought out fancy for loop, and it's portable (and presumably will make it's way into C++ some day and is future proof too).

justinhj
+1  A: 

For small collections, it should matter and foreach tends to be clearer.

However, for larger collections, for will begin to beat foreach at some point. (assuming that the 'at()' operator is efficient.

If this is really important (and I'm assuming it is since you are asking) then the best thing to do is measure it. A profiler should do the trick, or you could build a test version with some instrumentation.

Foredecker
A: 

I would expect foreach to work nominally faster in some cases, and the about same in others, except in cases where the items are an actual array in which case the performace difference is negligible.

If it is implemented on top of an enumerator, it may be more efficient than a straight indexing, depending on implementation. It's unlikely to be less efficient. For example, if someone exposed a balanced tree as both indexable and enumerable, then foreach will be decently faster. This is because each index will have to independently find the referenced item, while an enumerator has the context of the current node to more efficiently navigate to the next ont.

If you have an actual array, then it depends on the implementation of the language and class whether foreach will be faster for the same as for.

If indexing is a literal memory offset(such as C++), then for should be marginally faster since you're avoiding a function call. If indexing is an indirection just like a call, then it should be the same.

All that being said... I find it hard to find a case for generalization here. This is the last sort of optimization you should be looking for, even if there is a performance problem in your application. If you have a performance problem that can be solved by changing how you iterate, you don't really have a performance problem. You have a BUG, because someone wrote either a really crappy iterator, or a really crappy indexer.

Darren Clark
A: 

You might look at the STL's for_each function. I don't know whether it will be faster than the two options you present, but it is more standardized than the Qt foreach and avoids some of the problems that you may run into with a regular for loop (namely out of bounds indexing and difficulties with translating the loop to a different data structure).

Jason Baker
+4  A: 

First off, I'd just like to say I agree with Pax, and that the speed probably doesn't enter into it. foreach wins hands down based on readability, and that's enough in 98% of cases.

But of course the Qt guys have looked into and actually done some profiling: http://labs.trolltech.com/blogs/2009/01/23/iterating-efficiently/

The main lesson to take away from that is, use const references in read only loops as it avoids the creation of temporary instances. It also make the purpose of the loop more explicit, regardless of the looping method you use.

Parker
+1  A: 

First, I completely agree with the answer that "it doesn't matter". Pick the cleanest solution, and optimize if it becomes a problem.

But another way to look at it is that often, the fastest solution is the one that describes your intent most accurately. In this case, QT's foreach says that you'd like to apply some action for each element in the container.

A plain for loop say that you'd like a counter i. You want to repeatedly add one to this value i, and as long as it is less than the number of elements in the container, you would like to perform some action.

In other words, the plain for loop overspecifies the problem. It adds a lot of requirements that aren't actually part of what you're trying to do. You don't care about the loop counter. But as soon as you write a for loop, it has to be there.

On the other hand, the QT people have made no additional promises that may affect performance. They simply guarantee to iterate through the container and apply an action to each.

In other words, often the cleanest and most elegant solution is also the fastest.

jalf
+2  A: 

It really doesn't matter. Odds are if your program is slow, this isn't the problem. However, it should be noted that you aren't make a completely equal comparison. Qt's foreach is more similar to this (this example will use QList<QString>):

for(QList<QString>::iterator it = Con.begin(); it != Con.end(); ++it) {
    QString &str = *it;
    // your code here
}

The macro is able to do this by using some compiler extensions (like GCC's __typeof__) to get the type of the container passed. Also imagine that boost's BOOST_FOREACH is very similar in concept.

The reason why your example isn't fair is that your non-Qt version is adding extra work.

  1. you are indexing instead of really iterating. If you are using a type with non-contiguous allocation (I suspect this might be the case with QList<>), then indexing will be more expensive since the code has to calculate "where" the n-th item is.

  2. you are indexing using the at() function instead of operator[]. This function is usually implemented in such a way that is more expensive than operator[]. This because at() (at least the libstdc++ versions) are required to do bounds checking (unnecessary in this example's case, all indexes are in bounds) and potentially throw an exception. operator[] does not have this requirement (hypothetically it is legal for it to do the bounds checking, but that doesn't make sense in practice because that goes against expectations).

That being said. It still doesn't matter. The timing difference between those two pieces of code will be negligible if existent at all. Don't waste your time worrying about it. Write whichever you find more clear and understandable.

Evan Teran
A: 

I don't want to answer the question which is faster, but I do want to say which is better.

The biggest problem with Qt's foreach is the fact that it takes a copy of your container before iterating over it. You could say 'this doesn't matter because Qt classes are refcounted' but because a copy is used you don't actually change your original container at all.

In summary, Qt's foreach can only be used for read-only loops and thus should be avoided. Qt will happily let you write a foreach loop which you think will update/modify your container but in the end all changes are thrown away.

+1  A: 

A benchmark, and its results, on this can be found at http://richelbilderbeek.nl/CppExerciseAddOneAnswer.htm

IMHO (and many others here) it (that is speed) does not matter.

But feel free to draw your own conclusions.

Bilderbikkel