这是一些代码:
void f()
{
// stuff
{
// code
}
}
也可以使用 lambda 代替大括号以一种奇怪的方式编写它:
void f()
{
// same stuff as above
[&]{
// same code as above
}();
}
两个版本之间会有性能差异吗?
根据我的检查,当使用优化编译时,clang 中生成的程序集没有差异,因此我假设不会有性能开销。但情况总是如此吗?
绩效很难衡量。但在这种情况下,推理仍然是合理的。
每个 lambda 实际上都是它自己的类,并且实现了
operator()
。此类与在未命名命名空间中编写的类具有相同的特征。一些相关元素:它的可见性仅限于 .cpp
文件并链接到它,不需要公开 .obj
文件中的函数指针。
编译器可以对立即调用的 lambda 做哪些不同的事情?实际上没什么:它可以防止内联它。根据我的经验,这与未命名函数具有相同的行为:函数太大或被多次使用。最后一个可能是函数返回 lambda 的结果。
如果函数太大,则可能是某些未调用该函数的路径通过不内联它而更快。 如果多次调用它,它会放大您的二进制文件以将其内联两次,这可能会减慢速度。
对我来说,更大的风险是你用 lambda 调用像
std::sort
这样的模板化函数,并将该函数体复制到各处以使你的二进制文件膨胀。然而,由于这些之前已经是模板,并且 std:: function
以其可测量的性能效果而闻名,我认为这不值得付出努力。
也就是说,我到处都使用 lambda。我什至提供了类模板,将它们作为性能关键代码中的成员。 Lambda 被认为是零开销,但根据您使用它们的方式,您可能会发现程序中的流程变慢的边缘情况。
最后一点建议,即使在 C++ 这样的语言中,可读性也很重要。拥有大的 lambda 不被认为是可读的。我见过样式指南规则将其限制为 5 或 10 行。 立即调用的 lambda 有其用途,但是,对于您的示例,从读者的角度来看,这实际上只是开销。
快去测量吧!如果您有性能关键代码,请编写性能测试以进行持续监控,并时不时运行分析器以查看时间花在哪里。