I want to inline a lambda expression since it is very short for performance reason. Is it possible?
6 Answers
The inline
keyword does not actually cause functions to be inlined. Any recent compiler is going to make better decisions with regards to inlining than you will.
In the case of a short lambda, the function will probably be inlined.
If you're trying to use the inline
keyword with a lambda, the answer is no, you can't use that.

- 104,103
- 58
- 317
- 552
-
4It is trivially easy to come up with counterexamples to the claim that a recent compiler will make better decisions about in-lining than a given human will. I am not a C guru at all yet when I have had speed critical code, tagging a method with an inline hint often produces a faster executable. All one has to do is measure the code. I would advise anyone who has been told that the compiler knows better to set up a test bed where they can time various functions with and without inline hints to explore when you can outsmart the compiler. – jackmott Feb 12 '16 at 13:16
-
1@jack Of course. But you need things like __declspec(forceinline) or __declspec(noinline) to do that. If doing that makes any measurable improvement, 1. you need more LTO / LTCG, 2. you need more PGO, or 3. compiler bugs. Compilers don't do everything people claim that they do all the time, but inlining is one of those areas where they are generally really really good. – Billy ONeal Feb 12 '16 at 14:58
The compiler will inline it if it can. For example, in g++ 4.5 with -O2,
#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;
}
generates the assembly that the 2*x
and printf
lambdas are completely inlined.
# 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

- 510,854
- 105
- 1,084
- 1,005
It is possible that a lambda expression might be inlined. Under the hood, a lambda expression is no different than any other function object.
Whether a particular lambda expression is inlined is entirely dependent upon the compiler and whether it decides it is worth inlining.

- 348,265
- 75
- 913
- 977
If you have a regular struct functor, the compiler will almost certainly inline it. If you have a C++0x style lambda, the compiler will almost certainly inline it. If you're using a boost::lambda, then it might do, depending on how the lambda works underneath the scenes. Short version: You can't guarantee it's inlining or non-inlining, but you should trust your compiler and if in doubt, make it easy and simple to inline.

- 144,682
- 38
- 256
- 465
I haven't looked at the output from a lot of them by any means, but so far all of them I've looked at the output from have been inlined.

- 476,176
- 80
- 629
- 1,111
C++1x' lambdas will, under the hood, generate normal function objects. Those can be inlined by the compiler.
Did any measurements you made suggest the compiler did not inline them in a place where this leads to a notable performance loss?

- 219,715
- 46
- 258
- 445
-
1Nitpick: No work on C++1x has started yet, and it's nothing more than an educated guess that there even will be a C++1x. The committee is still working on C++0x, and it's not likely that the working title will be changed, just because it won't match the final short title of the standard. – Christopher Creutzig Jul 22 '10 at 14:16
-
@Christopher: I disagree. It's likely that the next C++ standard will be C++11, it might become C++12, it's unlikely to become C++10, and impossible to become C++09. Since the last (and only the last) digit is uncertain, it's commonly replaced by an `x`. Whether it will have lambdas is certainly not guaranteed (just look at consepts), but it's __very__ unlikely the committee would settle for anything less. – sbi Jul 22 '10 at 14:20
-
The joke is that the 0x is hex now, as most people continue to use C++0x – ZachS Jul 26 '10 at 20:27