17

I just finished learning about lambda expressions and was wondering whether an expression or a regular function would execute faster when printing to a console using cout.

Should I use

// Lambda expression
auto helloWorld = []()
{
    cout << "Hello World" << endl;
};

or

// Normal function
void helloWorld()
{
    cout << "Hello World" << endl;
}

Note: I am still a novice programmer, so do feel free to point out any errors I may have made. I can only learn

Thanks

Levi
  • 1,921
  • 1
  • 14
  • 18
  • 3
    A decent compiler shouldn't make any difference. If this question remains open, I'm about to see bunch of assemblies, which I hardly get. – P0W Aug 27 '14 at 06:33
  • 4
    Not a duplicate, because this question wonders specifically about the _content_ of the lambda which isn't addressed in the suggested duplicate. – MSalters Aug 27 '14 at 12:18

3 Answers3

28

I think lambda is elegant when using stl functions like , or you want quick throw away functions without naming them .

sort(v.begin(),
     v.end(),
     [](int a, int b){ return a > b; }
);

but it's not faster from the function .

Disassembly of both .

    helloWorld1();
008112A0  mov         ecx,dword ptr ds:[813054h]  
008112A6  push        8119A0h  
008112AB  call        std::operator<<<std::char_traits<char> > (0811780h)  
008112B0  mov         ecx,eax  
008112B2  call        dword ptr ds:[813038h]  
    helloWorld2();
008112B8  mov         ecx,dword ptr ds:[813054h]  
008112BE  push        8119A0h  
008112C3  call        std::operator<<<std::char_traits<char> > (0811780h)  
008112C8  mov         ecx,eax  
008112CA  call        dword ptr ds:[813038h] 

both have the same disassembly.

  • 7
    You should specify the disassembly of what compiler with what options : you showed the assembly of the function itself, it doesnt tell how the compiler optimizes the calls. – quantdev Aug 27 '14 at 06:37
  • @quantdev I used visual studio 2013 disassembly. –  Aug 27 '14 at 06:41
15

Since IO is involved, giving a damn about a few cycles of efficiency is pointless. What's more important is simplicity. Functions are entirely adequate for the job you present and can't be beaten. For a job that only a Lambda can solve, ...

Reserve lambda's for when they are clearly a good solution. They have advantages and costs that make them a very powerful tool for use in complex situations. If you can't choose between a lambda and an ordinary function, then the obvious choice is not the lambda.

  • 1
    Lambdas in c++ are mainly used to pass functions to other functions, right? – lightandlight Aug 27 '14 at 06:35
  • 5
    Of course, everything you can do with a lambda, you can do with a function object class. The main attraction, imo, of lambdas over functions or function object classes is for when you have a very special purpose that won't be generally useful outside the current function. And a function which prints `"Hello World"` probably isn't generally useful, so that might well be suitable for a lambda, if such a function is needed in some particular instance. – Benjamin Lindley Aug 27 '14 at 06:45
  • 1
    IIRC, a lambda *is* a function object (with its own effectively-anonymous class and everything). The lambda syntax really just avoids you having to create those classes yourself, which is great for one-off scenarios. – cHao Aug 27 '14 at 14:55
  • +1 for the good answer – Andy_A̷n̷d̷y̷ Oct 30 '14 at 07:01
6

Lambdas are an inplace way to create function objects. Function objects are usually used in places were in C one employs function pointers as callbacks.

One example could be C qsort function. To be able to sort an array of any type you have to give it the address of a function that will receive pointers to two elements of the array and return and integer indicating if the first is less (should be ordered before) than the second.:

void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*,const void*));

In the other side std::sort doesn't need a comparator function:

template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);

but if you need to pass one to specify a different order you can do it by passing a function object:

template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

You can create that function object using a lambda:

sort(v.begin(),
     v.end(),
     [](int a, int b){ return a > b; }
);

The intended uses of lambdas, function objects and function pointers are to pass as parameters to algorithms, as callbacks to get notified when something happens and similar cases.

To divide the code in meaningful named pieces you split it in well defined functions. To pass a function as a parameter to other functions a function object is a great way to do. If the function object is very small, it's only used once or you see no benefit in giving it a name, you can write your function object as a lambda.

Your question was about performance. Function objects (and lambdas) compares to function pointers. They can perform much faster.

If you look at qsort it will receive the address of a function and it will do a function call each time it has to compare. There is no way to inline because qsort and your function are compiled separately.

In std::sort example the lambda code is available at compile time and if it's simple enough the compiler will choose to inline and avoid all functions calls.

Yesterday at isocpp.org linked to a wonderful blog post titled Demystifying C++ lambdas that I strongly recommend.

Rndp13
  • 1,094
  • 1
  • 21
  • 35
davidaf
  • 351
  • 1
  • 4