Can/does the compiler inline lambda functions to increase efficiency, as it might with simple standard functions?
e.g.
std::vector<double> vd;
std::for_each(vd.begin(), vd.end(), [](const double d) {return d*d;});
Or is there loss of efficiency caused by lack of optimisation?
A second question: where I can check if the compiler I use has optimised calls of inline functions, which are sent to an algorithm? What I mean is, if a function—not a function object—is sent to an algorithm, the last one gets a pointer to the function, and some compilers optimize pointers to inline functions and others don't.
It depends on the optimisation level given to the compiler. Take for example, these two functions, which are semantically identical. One is C++11 style, the other C style.
Compiling this with gcc -O4 emits code which is extremely similar (not identical, but equivalent complexity) for the two functions.
However the lambda is not inlined when compiling unoptimised (and neither are the std::begin and std::end calls).
So although the compiler can (and does) do an excellent job at optimizing the modern style code when asked to do so, there is possibly or probably going to be a performance penalty for this kind of code in an unoptimized debug build.
First off: the whole point of the design of lambdas in C++ is that they don’t have an overhead compared to function calls. That notably includes the fact that calls to them can be inlined.
But there’s a confusion of concepts here: in the C++ standard, “inline” is the linkage of a function, i.e. it is a statement about how a function is defined, not how it gets called. Functions that are defined inline can benefit from a compiler optimisation by which calls to such functions are inlined. It’s a different but highly related concepts.
In the case of lambdas, the actual function being called is a member
operator()
that is implicitly defined asinline
in an anonymous class created by the compiler for the lambda. Calls of the lambda are translated to direct calls to itsoperator()
and can therefore be inlined. I’ve explained how the compiler creates lambda types in more detail in another answer.In simple cases, like your example, you should expect better performance with lambdas than with function pointers, see
Why can lambdas be better optimized by the compiler than plain functions?
As others have already pointed out, there is no guarantee that your call will be inlined but you have better chances with lambdas. One way of checking whether the call has been inlined is to check the generated code. If you are using gcc, pass the -S flag to the compiler. Of course, it assumes that you can understand the assembly code.
Update on Sep 11, 2018: Vipul Kumar pointed out two compiler flags in his edit.
GCC
-Winline
As I understand this, if your function is not declared inline, this compiler flag is most likely not helpful. Nevertheless it is good to know it exists and it partly answers your second question.
The other flag that he pointed out is:
Clang
-Rpass=inline
I haven't used this one myself but based on the documentation it might be useful for your use case.
I personally check the generated assembly whenever it is that important.