Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are lambdas inlined like functions in C++?

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.

like image 230
Illia Levandovskyi Avatar asked Apr 10 '13 15:04

Illia Levandovskyi


People also ask

Are lambda functions inlined?

Python lambda functions, also known as anonymous functions, are inline functions that do not have a name. They are created with the lambda keyword. This is part of the functional paradigm built-in Python. Python lambda functions are restricted to a single expression.

Are lambdas functors?

Lambdas are basically just syntactic sugar that implement functors (NB: closures are not simple.) In C++0x, you can use the auto keyword to store lambdas locally, and std::function will enable you to store lambdas, or pass them around in a type-safe manner.

Are lambdas faster than functions?

Being anonymous, lambda functions can be easily passed without being assigned to a variable. Lambda functions are inline functions and thus execute comparatively faster.

Are lambdas Pythonic?

Best practices for using Python lambdasPerceived as very Pythonic, lambdas are one of the favorite features in Python programming. So much so, that many Python programmers are tempted to use them whenever possible.


2 Answers

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

Warn if a function that is declared as inline cannot be inlined. Even with this option, the compiler does not warn about failures to inline functions declared in system headers.

The compiler uses a variety of heuristics to determine whether or not to inline a function. For example, the compiler takes into account the size of the function being inlined and the amount of inlining that has already been done in the current function. Therefore, seemingly insignificant changes in the source program can cause the warnings produced by -Winline to appear or disappear.

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

Options to Emit Optimization Reports

Optimization reports trace, at a high-level, all the major decisions done by compiler transformations. For instance, when the inliner decides to inline function foo() into bar() [...]

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.

like image 97
Ali Avatar answered Oct 07 '22 17:10

Ali


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 as inline in an anonymous class created by the compiler for the lambda. Calls of the lambda are translated to direct calls to its operator() and can therefore be inlined. I’ve explained how the compiler creates lambda types in more detail in another answer.

like image 44
Konrad Rudolph Avatar answered Oct 07 '22 18:10

Konrad Rudolph