Lambda函数性能对捕获的影响

时间:2015-10-01 22:54:41

标签: c++ lambda

我刚写了一个非常大的捕获:

[this, &newIndex, &indexedDirs, &filters, &flags, &indexRecursion](){...

我将这个lambda(indexRecursion)用于带有元素元素的递归,并问自己,使用“全局”捕获[&]是否更有效。由于我不知道捕获的实现,我需要一些解释。请带背景。

2 个答案:

答案 0 :(得分:4)

通常你可以认为lambda与此相当:

class ANON {
  int data;
  public:
    void operator ()(void) const {
      cout << data << endl;
    }
} lambda;
// auto lambda = [data]() {cout << data << endl;}

这可以让您了解如何实现捕获。捕获所有(通过复制=或引用&)可能只是语法糖,用于指定当前范围内捕获的所有已使用/可用变量。

但是因为......

  

[..]实现可以定义闭包类型与下面描述的不同,前提是这不会改变程序的可观察行为,只需更改:[..]闭包类型的大小和/或对齐方式[..]

     

[N4431§5.1.2/ 3]

...实现使用某种“黑魔法”来捕获所有引用lambdas并使用指向捕获的堆栈帧的指针,重写对变量的访问作为对某些偏移的访问是合法的。那个指针:

class ANON {
  void * stack_frame;
  public:
    void operator ()(void) const {
      cout << *static_cast<int *>(stack_frame + 8) << endl;
    }
} lambda;

所以使用& 可能(有一天)会更有效率,但正如已经说过的那样,这是实现定义的,没有什么可以依赖的。

答案 1 :(得分:2)

内部lambdas /通常/实现为ad-hoc类,其单个实例对象在lambda定义点构造,并且暴露了稍后要调用的functor。因此,应将lambda性能与使用std::bind将方法传递给函数进行比较。

捕获也不是神秘的实体。如果捕获是引用捕获,那么它们引用的实体在像往常一样走出范围时会被破坏,所以要注意你的lambda是否不是本地的:在它的体内它可能引用已经被破坏的对象。 / p>