Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does passing lambda by value or reference make it easier to inline?

Tags:

c++

lambda

c++14

A similar question has been asked before, but I'm still confused. The STL, I believe, exclusively passes by value, as passing by reference might have consequences in a multi-threaded environment. Say, when two or more threads are executing a mutable lambda. I currently use a universal reference when I just want to invoke a lambda:

template <typename F>
inline void invoke(F&& f)
{
  f();
}

This binds to any function object, just like a const& would, but maybe it's a bad idea for inlining. Is a lambda passed by copy easier to inline by the compiler? I'd like the passed lambdas to be as "inlinable" as possible.

like image 376
user1095108 Avatar asked Mar 08 '16 11:03

user1095108


1 Answers

Think of a lambda as a small object with a function call operator:

int foo = 1000;
auto f = [=]() ->int { return foo; };

is somewhat equivalent to:

class FooLambda {
    int foo;
  public:
    FooLambda(int foo) : foo(foo) {}
    int operator()(){ return foo; }
};
// ...
int foo = 1000;
FooLambda f(foo);

So you see, the function body itself can be inlined if it is seen in the same translation unit as it is called (and possibly if not by some smarter compilers). Since your invoke is a template, it knows the actual type of the lamdba, and you don't force it to jump through function-pointer hoops, which a big inhibitor of inlining.

Taking the callable object by value or reference in invoke determines whether the captured variables are local to the function body or not, which can make a difference if it means they will be in cache.

like image 62
BoBTFish Avatar answered Oct 18 '22 13:10

BoBTFish