C++ C++;各11个用于_和lambdas优化

C++ C++;各11个用于_和lambdas优化,c++,lambda,g++,c++11,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_eac

我正在测试以下代码:

#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;
}
使用-O1优化会产生以下(毫不奇怪)结果:

我在双核2Ghz笔记本电脑上运行Linux3.0,如果有必要的话

我想知道的是,在一个没有任何优化的编译程序中,使用lambda函数调用for_怎么会比普通for循环占用更少的时钟?调用匿名函数难道不应该有一点开销吗?有没有关于如何编写这样的代码的文档

 std::for_each(v.begin(), v.end(), [](int& it){ it = 10098; });
是否由g++处理?在这种情况下,其他流行编译器的行为是什么

更新


在每次迭代中,我没有考虑第二个表达式中的<代码> IT <代码>与<代码> v结尾()/代码>的比较。有了这个固定值,for循环消耗的时钟比for\u少。然而,当使用-O1标志时,我仍然对编译器如何优化for_each感到好奇。

乍一看,我至少可以说这些表达式是不等价的。请尝试以下方法:

  for(auto it = v.begin(), end = v.end(); it != end; ++it) *it = 98775;
此外,由于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());

除了内联,这将导致与for循环(包括我的修改)非常相同的代码。

有趣的是,即使在进行了“end=v.end(),i!=end”优化之后,for_each&lambda案例在Visual Studio 2010的调试模式下仍然运行得更快


在VS2010中,使其更快的一个优化是,元模板机制可以检测向量迭代器的使用,并切换到在开始/结束时使用指向整数的原始指针,这消除了调试模式下运算符++、运算符*、运算符!=的大量验证检查

试过了。结案:)
[javadyan@myhost实验]$/每年26万次[javadyan@myhost实验]$./a.out aaa 180000
@GrigoryJavadyan:出于好奇,启用优化后的结果是什么?:)仍然希望听到关于使用-O1时g++如何显著减少第一个表达式(使用lambda)的周期数的解释。我想匿名函数是内联的还是什么?@GrigoryJavadyan:是的,我明白了。顺便说一句,
clock()
在衡量性能时是一个巨大的失败。作为回报,它的精度下降了数千倍。尝试使用高精度的挂钟,比如带有单调标志的
clock\u gettime()
。@grigori确保在优化时执行代码。您没有使用结果。如果我是C++编译器,我会逐个删除整个代码(除了某些任意时间的输出)。由于这个原因,您当前的基准代码存在缺陷。一定要改变它,使其产生副作用,防止编译器省略任何代码。
  for(auto it = v.begin(), end = v.end(); it != end; ++it) *it = 98775;
class __lambda_function_123
{
public:
    void operator()(int& it) const{ it = 10098; }
};

std::for_each(v.begin(), v.end(), __lambda_function_123());