在其他函数或循环中构造 lambda 时是否存在性能问题?

Are there performance concerns when constructing lambdas inside other functions or loops?

在 JavaScript、Mozilla recommends 中,如果不需要闭包,则不应在其他函数内创建函数,因为这会对脚本性能产生负面影响。在 JavaScript 中,同样的问题适用于在循环内创建函数。同样的问题是否适用于 C++ lambdas?

例如,这两个函数之间是否存在性能差异:

int f1(vector<int> v) {
    for_each(v.begin(), v.end(), [](int i) { cout << i << endl; });
}

auto print_int = [](int i) { cout << i << endl; };
int f2(vector<int> v) {
    for_each(v.begin(), v.end(), print_int);
}

我想是的,这些问题适用于 C++,并且 f2 的性能将优于 f1;但是,我一直没能找到明确的答案。

这取决于编译器,或者更确切地说,取决于它的优化器。

如果它发现它可以内联 print_int,那么 f1()f2() 的性能将是相同的。

如果没有,那么,f2() 可能会生成实际的函数调用(即 x86 汇编程序中的 CALL),而 f1() 可能会内联代码以避免函数调用.

但是,在任何情况下,"lambda" 都不太可能在每次传递中创建。 Lambda 只是具有重载函数调用运算符的局部 class 对象的语法糖。

不,在现实生活中的编译器中不会有性能差异,因为 C++ 编译器可能会为这两个函数生成完全相同的汇编代码。

通常,您不应将为脚本语言设计的指南应用于编译语言,因为它们在编译阶段发生的事情(因此与 运行 时间性能无关)与实际情况有很大不同发生在 运行 时间。

不,我希望您代码中的两个示例不会对速度产生任何影响。这两个语句对于编译器来说非常相似。

此外,lambda 表达式在性能方面可能是一个非常危险的结构。根据整个构造,编译器可以或多或少地优化函数调用。使用类似于函数指针的 lambda 会给你带来灾难性的性能结果,例如使用 std::function 作为 lambda 函数指针的包装器(例如 What is the performance overhead of std::function?

不,是的。

对于简单的 lambda,没关系。这是因为对于带有 operator() 的 class,lambda 是一个简单的 shorthand。

相关元素是 class 有一个构造函数。想象一下:

std::map<std::string, std::string> m = create();
auto lambda = [m]() { /* code */ };

在循环中执行此捕获没有意义,因为您复制了很多不应更改的字符串。 在这种情况下,通过引用捕获也可能有意义。

我的建议是:和其他人一样class。如果构建起来很简单,只需将其放置在您认为合乎逻辑的位置即可。如果造价高,想一想为什么这么贵,可能的话考虑搬出去。