C++ 11 for_each和lambdas优化

4 c++ lambda g++ c++11

我正在测试以下代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
int main(int argc, char* argv[])
{
   std::vector<int> v(10000000);
   clock_t then = clock();
   if(argc <= 1)
      std::for_each(v.begin(), v.end(), [](int& it){ it = 10098; });
   else
      for(auto it = v.begin(); it != v.end(); ++it) *it = 98775;
   std::cout << clock() - then << "\n";
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用g ++ 4.6编译它,没有任何优化标志,这就是我得到的:

[javadyan@myhost experiments]$ ./a.out 
260000
[javadyan@myhost experiments]$ ./a.out aaa
330000
[javadyan@myhost experiments]$ 
Run Code Online (Sandbox Code Playgroud)

使用-O1优化会产生以下(不足为奇)的结果:

[javadyan@myhost experiments]$ ./a.out 
20000
[javadyan@myhost experiments]$ ./a.out aaa
20000
Run Code Online (Sandbox Code Playgroud)

我在双核2Ghz笔记本电脑上运行Linux 3.0,如果这很重要的话.

我想知道的是,如果在没有任何优化的情况下编译的程序如何使用lambda函数调用for_each可以比普通for循环少吃掉时钟?调用匿名函数不应该有轻微的开销吗?有没有关于代码如何这样的文档

 std::for_each(v.begin(), v.end(), [](int& it){ it = 10098; });
Run Code Online (Sandbox Code Playgroud)

由g ++处理?在这种情况下,其他流行编译器的行为是什么?

UPDATE

我没有考虑it在第二个表达式中与v.end()每次迭代进行比较的事实.通过修复,for循环比for_each节省更少的时钟.但是,我仍然很好奇编译器在使用-O1标志时如何优化for_each.

K-b*_*llo 7

乍一看,我至少可以说这些表达方式并不相同.试试这个:

  for(auto it = v.begin(), end = v.end(); it != end; ++it) *it = 98775;
Run Code Online (Sandbox Code Playgroud)

此外,由于传递了lambda的确切类型,for_each编译器很可能会内联它,导致代码与for循环没有区别.请注意,匿名函数中不涉及虚​​拟调用.编译器将执行以下操作:

class __lambda_function_123
{
public:
    void operator()(int& it) const{ it = 10098; }
};

std::for_each(v.begin(), v.end(), __lambda_function_123());
Run Code Online (Sandbox Code Playgroud)

除了内联之外,它将产生与for循环完全相同的代码(包含我的修改).

  • @GrigoryJavadyan:是的,我明白了.顺便说一句,`clock()`在测量性能时是一个史诗般的失败.它的精确度可以减少数千.尝试使用高精度挂钟,如带有MONOTONIC标志的`clock_gettime()`. (2认同)
  • @Grigory确保在优化时完全执行代码.您没有使用结果.如果我是C++编译器,我会忽略整个代码(除了一些任意时间的输出).由于这个原因,您当前的基准代码存在缺陷.请将其更改为具有阻止编译器忽略任何代码的副作用. (2认同)