Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ Should I define lambda out of for loop or inside it to keep small scope, what is best practice

Tags:

c++

c++11

lambda

I have a code where I have two options, define lambda out of loop to save on lambda creation overhead or define it inside a loop to keep small scope.

Is this choice critical and will make any significant difference?

What are pros and cons of this two choices?

What is best practice?

#include <iostream>
#include <string>
#include <vector>
#include <memory>

int main()
{
  std::vector<std::function<void()>> functors;
  auto func = [] () { std::cout << "Hello world I am doing some action"; };
  //some code here
  for(int i = 0; i < 100; ++i)
  {
      // some code here
      functors.push_back(func);
      // some code here
  }
}

EDITED: simplified example

int main()
{
  auto sum = [](const int x, const  int y) { return x + y; };
  for(int i = 0; i < 100; ++i)
  {
      std::cout << sum(i, i + 1) << std::endl;
  }
}
like image 378
T M Avatar asked Jul 11 '16 13:07

T M


People also ask

How do you use lambda function instead of for loop?

Since a for loop is a statement (as is print , in Python 2. x), you cannot include it in a lambda expression. Instead, you need to use the write method on sys. stdout along with the join method.

Which of the following statement is correct about lambda expression?

What is the correct statement about lambda expression? Explanation: Return type in lambda expression can be ignored in some cases as the compiler will itself figure that out but not in all cases. Lambda expression is used to define small functions, not large functions.

What are the two conditions required for using a lambda function in a stream?

In order to match a lambda to a single method interface, also called a "functional interface", several conditions need to be met: The functional interface has to have exactly one unimplemented method, and that method (naturally) has to be abstract.

Can we write for loop in lambda function?

Using a lambda function with a for loop is certainly not the way to approach problems like these. Instead, you can simply use a list comprehension to iterate over the given string/list/collection and print it accordingly, as shown in the solution below.


2 Answers

For each lambda expression, the compiler will create a struct with operator () overloaded for it. It won't create a struct each time the control passes through a lambda, so in terms of generated code it does not matter whether you define it inside or outside the loop. Therefore, keep things local.

As a general rule, don't overthink these illusory optimization issues. Most likely, the performance bottleneck is going to be in your algorithm complexity.

like image 174
Armen Tsirunyan Avatar answered Oct 28 '22 14:10

Armen Tsirunyan


I'd rather wipe out a copy construction and move construct instead by using emplace_back directly (not so useful in this case, but as a rule of thumb one should prefer it whenever possible):

#include <iostream>
#include <string>
#include <vector>
#include <memory>

int main()
{
    std::vector<std::function<void()>> functors;
    //some code here
    for(int i = 0; i < 100; ++i)
    {
        // some code here
        functors.emplace_back([] () { std::cout << "Hello world I am doing some action"; });
        // some code here
    }
}

That said, I agree with @ArmenTsirunyan and I'd avoid premature optimizations of such a type.

like image 43
skypjack Avatar answered Oct 28 '22 13:10

skypjack