28

Is there any overhead associated with using lambda expressions in C++0x (under VS2010)?
I know that using function objects incurs overhead, but I'm referring to expressions that are passed to STL algorithms, for example. Does the compiler optimize the expression, eliminating what seems to appear like a function call? I started to really like lambda expressions, but I'm a bit concerned about the speed penalty.

Thanks in advance!

asked Jul 10, 2010 at 10:38
3
  • 7
    Why are you sure using function objects (functors) incurs overhead? They can be optimized too! The only way to know is to build with full optimizations enabled and then look at the assembly. Commented Jul 10, 2010 at 10:40
  • When I said function object I was referring to something like boost::function, my fault. I know that classic function objects can be inlined, and I wanted to know if this happens with lambdas too. Commented Jul 10, 2010 at 10:50
  • ah ok, those do have some overhead. But Lambdas don't (unless you wrap them in a std::function object (don't need to use boost, since that has been adopted into the 0x standard Commented Jul 10, 2010 at 11:02

2 Answers 2

50

You "know" that function objects incur overhead? Perhaps you should recheck your facts. :)

There is typically zero overhead to using a STL algorithm with a function object, compared with a hand-rolled loop. A naive compiler will have to repeatedly call operator() on the functor, but that is trivial to inline and so in effect, the overhead is zero.

A lambda expression is nothing more than syntactic sugar for a function object. The code is transformed into a function object by the compiler, so it too has zero overhead.

answered Jul 10, 2010 at 10:48
Sign up to request clarification or add additional context in comments.

6 Comments

Empirically, this is false. Adding a lot of instantiations of std::functions significantly increases the size of the executable, at least in VS2010. I just performed this test.
@shoosh: So? Adding a lot of instantiations of std:string incurs a lot of overhead too. But that wasn't what the question, or my answer, were about. They were about function objects and lambdas. std::function is neither.
just to elaborate, std::function is a wrapper class, an abstraction over all callable objects, whether function pointers or functors. And it is not free to use. But if you avoid the wrapper, and just use a functor, or a lambda, directly, there is zero overhead
@TomA: not exactly. A function template taking some type T can take a lambda as a parameter. Of course, for a non-template function, you have to specify the actual parameter type, and you can't do that if the type is a lambda, so in that case, you have to wrap it in a std::function or similar.
As jalf said, there is no need to wrap a lambda with std::function. std::function does pay abstraction overhead at runtime, but lambdas do not. Assuming your functors are optimized (ctor and operator() inlined), your lambda expressions do have zero overhead in comparison. Now whether you use lambdas or function objects directly, there is an overhead if you want to be able to store them and invoke them at runtime through std::function.
|
20

Under the hood,

void f(char delim)
{
 std::for_each( seq.begin()
 , seq.end()
 , [=](const T& obj){std::cout << obj << delim;} );
}

approximately translates into

class __local_class_name {
 char __delim;
public:
 __local_class_name(char delim) : __delim(delim) {}
 void operator()(const T& obj) {std::cout << obj << __delim;}
};
void f(char delim)
{
 std::for_each( seq.begin()
 , seq.end()
 , __local_class_name(delim) );
}

As with all function objects, the overhead is very minimal, since the call can easily be inlined.

Stack Overflow is garbage
249k53 gold badges356 silver badges558 bronze badges
answered Jul 10, 2010 at 10:44

7 Comments

He does; [=] indicates that all local objects should be captured by value.
@Dennis: Only jalf added the =, so @Dario was right. :( @jalf: Thanks. My excuse is that I hadn't had the time yet to play with this, so it's all typed from hearsay.
yeah, I should probably have left a comment saying I added it. :) But yeah, [=] captures everything by value. We could have used [delim] as well, to capture that variable specifically. Btw, I +1'ed your answer. :)
__local_class_name would be a local class in the scope of the function f. C++0x allows local class instances to be used as parameters to function templates (they are not allowed current standard). It's also worth noting that the class name is generated by the compiler for each lambda and you can not name the type of the lambda yourself.
@snk_kid: I was wondering about whether that class would be function-local or not. In the end I decided that, since didn't know, and since the name was supposed to be unique anyway, I would err to the safe side and put it into namespace scope. Can you cite chapter and verse? If so, I'd go and move it.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.