Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nesting Lambda functions - Performance implications

I have a top level lambda function and then there are couple of nested lambda functions inside this lambda.

Is it a good idea to nest lambdas inside other lambdas? Are there any performance implications?

For e.g.

auto Multiplier1 = []() -> int
{
    auto Multiplier2 = [](int i) -> int
    {
        auto Multiplier3 = [](int i) -> int
        {
            return i * 2;
        };
        std::cout << "Calling another lambda 2\n";
        return Multiplier3(i * 100);
    };

    int i = 10;
    std::cout << "Calling another lambda 1\n";
    int ret = Multiplier2(i);
    return ret;
};

int ret = Multiplier1();
std::cout << ret << "\n";

In the example above, I can re-factor Multiplier2 and Multiplier3 into separate functions. Is that a better approach compared to this?

I am modifying a code which is already in production and hence, I was in a dilemma whether to re-factor it into separate functions or manage using lambda functions.

like image 979
Manjunath Ballur Avatar asked May 27 '16 06:05

Manjunath Ballur


People also ask

Can you nest lambda functions?

Python allows lambda nesting, i.e., you can create another lambda function inside a pre-existing lambda function. For nesting lambdas, you will need to define two lambda functions – an outer and an inner lambda function. When the outer lambda is called, the inner lambda creates a function.

Is lambda function faster than normal function?

Lambda functions are inline functions and thus execute comparatively faster.

Do lambdas go out of scope?

A lambda object must not outlive any of its reference captured objects. Lambda expressions may capture objects with automatic storage duration from the set of enclosing scopes (called the reaching scope) for use in the lambda's function body.


1 Answers

Asking about performance implications as a result of expression of coding style is always the wrong question.

The compiler, when optimising, considers expressed intent, not the layout of your code.

This example is extreme but it's worth showing you the code produced by gcc with compiler option -O2.

Refactoring the code above to remove the noise that will be produced by the use of cout:

auto Multiplier1 = []() -> int
{
    auto Multiplier2 = [](int i) -> int
    {
        auto Multiplier3 = [](int i) -> int
        {
            return i * 2;
        };
        return Multiplier3(i * 100);
    };

    int i = 10;
    int ret = Multiplier2(i);
    return ret;
};

extern void emit(int);

int main()
{
    int ret = Multiplier1();
    emit(ret);
}

compiling with gcc -S -O2 -std=c++14 yields:

main:
        subq    $8, %rsp
        movl    $2000, %edi
        call    emit(int)
        xorl    %eax, %eax
        addq    $8, %rsp
        ret

Notice that the optimiser has seen through all the code and realised that the only course of action this code could ever take (that matters) is to call the function emit with the argument value of 2000.

The lesson is always that one should express intent elegantly (i.e. in a way that can be understood and maintained easily) and allow the compiler to do its job of emitting code that implements that intent in the least time and/or code size.

like image 105
Richard Hodges Avatar answered Sep 23 '22 12:09

Richard Hodges