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

问题描述 投票:3回答:4

在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;但是,我还没有找到明确的答案。

c++ performance c++11 lambda anonymous-function
4个回答
3
投票

不,是的。

对于简单的lambda来说,没关系。这是因为lambda是带有operator()的类的简单简写。

相关元素是类具有构造函数。想像:

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

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

我的建议是:和其他班级一样做。如果要构造,请将其放置在您认为合乎逻辑的位置。如果建造成本高,请考虑为什么这么贵,并考虑在可能的情况下将其移出。


3
投票

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

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


1
投票

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

如果它拿起它可以内联print_int,那么f1()f2()的表现将是相同的。

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

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


0
投票

不,我希望你的代码中的两个例子都不会对速度做任何改变。两种语句对于编译器都非常相似。

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

© www.soinside.com 2019 - 2024. All rights reserved.