Performance compare (normal function call vs for_each+mem_fun vs lambda expression) in C++
Which is the best one (in performance) among these snippets?
1)
for(list<Enemy*>::iterator iter = enemies.begin(); iter != enemies.end(); iter ++)
(*iter)->prepare(time_elapsed);
2)
for_each(enemies.begin(), enemies.end(), [time_elapsed] (Enemy *e) {e->prepare(time_elapsed);});
3)
for_each(enemies.begin(), enemies.end(), bind2nd(m开发者_开发问答em_fun1<void, Enemy, GLfloat>(&Enemy::prepare), time_elapsed));
Lambdas are the fastest solution. There are special optimizations involved with taking references to stack-based variables. In addition, in C++0x, they're FAR more flexible than any of that bind stuff, and the first loop also has the clarity disadvantage. Lambdas are the winrar in every way.
However, I'm seriously thinking micro-optimization, unless this is in a really, really inner loop that runs billions of times.
I did the measurations with no compiler optimizations:
2) and 3) have almost the same running time, instead 1) is 10 times slower. I added also a 4)
for each (Enemy* e in enemies)
e->prepare(time_elapsed);
valid for Visual C++ 2010 and should be sematically the same of Ferruccio's:
for (var iter : enemies) { iter->prepare(time_elapsed); }
4) is also almost as fast as 2) and 3).
With -O2 all have almost the same running time.
2 and 3 are essentially identical. 1 might be faster because it performs one function call per iteration whereas 2 and 3 perform two function calls per iteration. Then again some of the function calls might get inlined. The only way to really tell is to measure.
Also, since you're throwing in lambda functions (C++0x), why not add range-based for loops to your measurements:
for (var iter : enemies) { iter->prepare(time_lapsed); }
assuming your compiler supports them, of course.
EDIT: I just noticed the vc++2010 tag. Unfortunately, your compiler does not yet support them :-(
The answer is "it's not at all important until you've measured that something is currently not fast enough". This question is essentially premature optimisation. Until it's too slow and you've measured the loop as being a bottleneck, your priority is to use the code that communicates what you're trying to do in the clearest way. Write nice code first, optimise later.
精彩评论