将代码包装在立即调用的 lambda 表达式中是否会带来性能差异?

问题描述 投票:0回答:1

这是一些代码:

void f() 
{
    // stuff
    {
        // code
    }
}

也可以使用 lambda 代替大括号以一种奇怪的方式编写它:

void f() 
{
    // same stuff as above
    [&]{
        // same code as above
    }();
}

两个版本之间会有性能差异吗?

根据我的检查,当使用优化编译时,clang 中生成的程序集没有差异,因此我假设不会有性能开销。但情况总是如此吗?

c++ lambda
1个回答
3
投票

绩效很难衡量。但在这种情况下,推理仍然是合理的。

每个 lambda 实际上都是它自己的类,并且实现了

operator()
。此类与在未命名命名空间中编写的类具有相同的特征。一些相关元素:它的可见性仅限于
.cpp
文件并链接到它,不需要公开
.obj
文件中的函数指针。

编译器可以对立即调用的 lambda 做哪些不同的事情?实际上没什么:它可以防止内联它。根据我的经验,这与未命名函数具有相同的行为:函数太大或被多次使用。最后一个可能是函数返回 lambda 的结果。

如果函数太大,则可能是某些未调用该函数的路径通过不内联它而更快。 如果多次调用它,它会放大您的二进制文件以将其内联两次,这可能会减慢速度。

对我来说,更大的风险是你用 lambda 调用像

std::sort
这样的模板化函数,并将该函数体复制到各处以使你的二进制文件膨胀。然而,由于这些之前已经是模板,并且
std:: function
以其可测量的性能效果而闻名,我认为这不值得付出努力。

也就是说,我到处都使用 lambda。我什至提供了类模板,将它们作为性能关键代码中的成员。 Lambda 被认为是零开销,但根据您使用它们的方式,您可能会发现程序中的流程变慢的边缘情况。

最后一点建议,即使在 C++ 这样的语言中,可读性也很重要。拥有大的 lambda 不被认为是可读的。我见过样式指南规则将其限制为 5 或 10 行。 立即调用的 lambda 有其用途,但是,对于您的示例,从读者的角度来看,这实际上只是开销。

快去测量吧!如果您有性能关键代码,请编写性能测试以进行持续监控,并时不时运行分析器以查看时间花在哪里。

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