我有一个顶级lambda函数,然后在这个lambda中有几个嵌套的lambda函数。
将lambda嵌入其他lambda中是个好主意吗?是否有任何性能影响?
例如
auto Multiplier1 = []() -> int
{
auto Multiplier2 = [](int i) -> int
{
auto Multiplier3 = [](int i) -> int
{
return i * 2;
};
std::cout << "Calling another lambda 2\n";
return Multiplier3(i * 100);
};
int i = 10;
std::cout << "Calling another lambda 1\n";
int ret = Multiplier2(i);
return ret;
};
int ret = Multiplier1();
std::cout << ret << "\n";
在上面的例子中,我可以将Multiplier2和Multiplier3重新分解为单独的函数。与此相比,这是一种更好的方法吗?
我正在修改已经在生产中的代码,因此,无论是将其重新分解为单独的函数还是使用lambda函数进行管理,我都处于两难境地。
答案 0 :(得分:13)
由于表达编码风格而询问性能影响始终是错误的问题。
编译器在优化时会考虑表达的意图,而不是代码的布局。
此示例非常极端,但值得向您展示gcc使用编译器选项-O2
生成的代码。
重构上面的代码,以消除使用cout
产生的噪音:
auto Multiplier1 = []() -> int
{
auto Multiplier2 = [](int i) -> int
{
auto Multiplier3 = [](int i) -> int
{
return i * 2;
};
return Multiplier3(i * 100);
};
int i = 10;
int ret = Multiplier2(i);
return ret;
};
extern void emit(int);
int main()
{
int ret = Multiplier1();
emit(ret);
}
使用gcc -S -O2 -std=c++14
进行编译:
main:
subq $8, %rsp
movl $2000, %edi
call emit(int)
xorl %eax, %eax
addq $8, %rsp
ret
请注意,优化器已经看过所有代码并意识到此代码可能采取的唯一操作过程(重要的)是使用参数值2000来调用函数emit
。
总而言之,人们应该优雅地表达意图(即以一种易于理解和维护的方式)并允许编译器完成其在最短时间和/或代码大小中发出实现该意图的代码的工作