C++ Lambda捕获变量与传参是否有性能差异?二者该如何选择?
针对你给出的两个Lambda示例:参数传入的lambdaFunction1和捕获变量的lambdaFunction2,我们分两部分回答:
性能差异
绝大多数开启编译器优化(比如O2及以上)的场景下,二者没有可观测的性能差异。
Lambda本质是编译器生成的匿名类实例:
- 作为参数传入的版本,调用时参数会按照函数调用约定走寄存器或者栈传递,执行逻辑时读取参数即可
- 作为捕获值的版本,值捕获会把变量存为匿名类的成员变量,引用捕获会把指针/引用存为成员变量,调用时直接读取成员即可
开启inline优化后,两种写法的中间开销都会被编译器消除,生成的汇编指令几乎一致。唯一可能出现差异的场景:
- 如果你需要多次调用同一个lambda,值捕获大对象只会在lambda创建时拷贝1次,而每次调用都传值参数会重复拷贝,此时捕获的性能明显更好
- 如果lambda只调用1次,二者的拷贝/传参开销完全对等
选择规则
二者都可用的场景下并不是只看个人习惯,有明确的优先选择原则:
- 优先匹配变量属性:如果变量是lambda的固定配置、需要在多次调用间复用状态,就选捕获;如果变量是每次调用都会变化的动态输入,就作为参数传入,保证调用点的可读性,其他人看调用代码就能直观看到每次传入的动态值是什么。
举个例子:做阈值过滤的lambda,阈值是创建时固定的配置,写为auto filter = [threshold](int val) { return val > threshold; };显然更合理,调用时只需要传被过滤的val即可,不需要每次都重复传相同的threshold。 - 优先规避生命周期风险:如果对应变量可能在lambda被调用前销毁,要么选值捕获,要么作为参数传入,不要用引用捕获。如果不想每次调用都重复传参就选值捕获,否则传参的生命周期安全性更可控。
- 优先保证const正确性:默认值捕获的变量在lambda内是只读的(除非加
mutable关键字),如果不需要修改变量,捕获可以天然保证const约束,比手动给参数加const更不容易出错。
内容的提问来源于stack exchange,提问作者Random
相关产品推荐
相关产品推荐

