【发布时间】:2011-03-19 13:57:06
【问题描述】:
我想内联一个 lambda 表达式,因为出于性能原因它非常短。有可能吗?
【问题讨论】:
-
由于函数是在类定义中定义的,反正默认是
inline。
标签: c++ c++11 lambda inline inlining
我想内联一个 lambda 表达式,因为出于性能原因它非常短。有可能吗?
【问题讨论】:
inline。
标签: c++ c++11 lambda inline inlining
inline 关键字实际上不会导致函数被内联。任何最近的编译器都会在内联方面做出比你更好的决定。
在短 lambda 的情况下,函数可能会被内联。
如果您尝试将 inline 关键字与 lambda 一起使用,答案是否定的,您不能使用它。
【讨论】:
如果可以的话,编译器会内联它。例如,在带有 -O2 的 g++ 4.5 中,
#include <vector>
#include <algorithm>
int main () {
std::vector<int> a(10);
for (int i = 0; i < 10; ++ i) a[i] = i;
asm ("Ltransform_begin: nop; nop; nop; nop; nop; nop; ");
std::transform(a.begin(), a.end(), a.begin(), [] (int x) { return 2*x; });
asm ("Lforeach_begin: nop; nop; nop; nop; nop; nop; ");
std::for_each(a.begin(), a.end(), [] (int x) { printf("%d\n", x); });
asm ("Lforeach_done: nop; nop; nop; nop; nop; nop; ");
return 0;
}
生成 2*x 和 printf lambda 完全内联的程序集。
# 9 "x.cpp" 1
Ltransform_begin: nop; nop; nop; nop; nop; nop;
# 0 "" 2
.align 4,0x90
L13:
sall (%rax)
addq $4, %rax
cmpq %rax, %r12
jne L13
# 13 "x.cpp" 1
Lforeach_begin: nop; nop; nop; nop; nop; nop;
# 0 "" 2
.align 4,0x90
L14:
movl (%rbx), %esi
leaq LC0(%rip), %rdi
xorl %eax, %eax
LEHB1:
call _printf
LEHE1:
addq $4, %rbx
cmpq %r12, %rbx
jne L14
# 17 "x.cpp" 1
Lforeach_done: nop; nop; nop; nop; nop; nop;
# 0 "" 2
【讨论】:
lambda 表达式可能是内联的。在底层,lambda 表达式与任何其他函数对象没有什么不同。
一个特定的 lambda 表达式是否被内联完全取决于编译器以及它是否决定它是否值得内联。
【讨论】:
如果你有一个常规的结构函子,编译器几乎肯定会内联它。如果你有一个 C++0x 风格的 lambda,编译器几乎肯定会内联它。如果您使用的是 boost::lambda,那么它可能会这样做,具体取决于 lambda 在场景下的工作方式。短版:你不能保证它是内联的还是非内联的,但你应该相信你的编译器,如果有疑问,让内联变得容易和简单。
【讨论】:
我还没有以任何方式查看其中 很多 个输出,但到目前为止,我查看的所有输出都已被内联。
【讨论】:
C++1x' lambdas 将在底层生成普通函数对象。这些可以由编译器内联。
您所做的任何测量是否表明编译器没有将它们内联到导致显着性能损失的地方?
【讨论】:
x。当然不能保证它是否会有 lambdas(只看概念),但委员会非常不太可能满足于更少的东西。