1

在这些片段中,哪一个是最好的(性能)?

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(mem_fun1<void, Enemy, GLfloat>(&Enemy::prepare), time_elapsed));
4

4 回答 4

1

我在没有编译器优化的情况下进行了测量:

2) 和 3) 的运行时间几乎相同,而 1) 则慢了 10 倍。我还添加了一个 4)

for each (Enemy* e in enemies)
      e->prepare(time_elapsed);

适用于 Visual C++ 2010 并且应该与 Ferruccio 的语义相同:

for (var iter : enemies) { iter->prepare(time_elapsed); }

4) 也几乎和 2) 和 3) 一样快。

使用 -O2 都具有几乎相同的运行时间。

于 2010-12-06T14:07:47.700 回答
1

Lambda 是最快的解决方案。引用基于堆栈的变量会涉及一些特殊的优化。此外,在 C++0x 中,它们比任何绑定的东西都要灵活得多,而且第一个循环也有清晰度的缺点。Lambda 在各个方面都是 winrar。

但是,我正在认真考虑微优化,除非这是在一个运行数十亿次的非常非常内部的循环中。

于 2010-12-06T14:38:29.543 回答
0

2和3基本相同。1 可能更快,因为它每次迭代执行一个函数调用,而 2 和 3 每次迭代执行两个函数调用。然后,一些函数调用可能会被内联。真正分辨的唯一方法是测量。

此外,既然您要使用 lambda 函数 (C++0x),为什么不在您的测量中添加基于范围的 for 循环:

for (var iter : enemies) { iter->prepare(time_lapsed); }

当然,假设您的编译器支持它们。

编辑:我刚刚注意到 vc++2010 标签。不幸的是,您的编译器还不支持它们:-(

于 2010-12-06T13:22:14.493 回答
0

答案是“在你测量到某些东西当前速度不够快之前,这并不重要”。这个问题本质上是过早的优化。在它太慢并且您将循环测量为瓶颈之前,您的首要任务是使用以最清晰的方式传达您正在尝试执行的操作的代码。先写好代码,再优化。

于 2010-12-06T14:22:45.033 回答