【问题标题】:Nesting Lambda functions - Performance implications嵌套 Lambda 函数 - 性能影响
【发布时间】:2016-05-27 06:06:15
【问题描述】:

我有一个顶级 lambda 函数,然后在这个 lambda 里面有几个嵌套的 lambda 函数。

将 lambdas 嵌套在其他 lambdas 中是个好主意吗?对性能有影响吗?

例如

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";

在上面的示例中,我可以将 Multiplier2 和 Multiplier3 重新分解为单独的函数。与此相比,这是更好的方法吗?

我正在修改一个已经投入生产的代码,因此,我处于两难境地,是将其重新分解为单独的函数还是使用 lambda 函数进行管理。

【问题讨论】:

  • "对性能有影响吗?" 对于无捕获的 lambdas,就像你一样,绝对不会。
  • 诚实的问题:为什么不围绕你拥有的罐头示例进行循环并计时。然后重构和时间?正如@ildjarn 指出的那样,您需要确保这些 lambda 的签名与您在生产中拥有的真实 lambda 完全等效。
  • @Hal 你是对的。最好的办法是计时并检查性能。

标签: c++ c++11 asynchronous lambda c++14


【解决方案1】:

询问编码风格表达对性能的影响总是错误的问题。

编译器在优化时会考虑表达的意图,而不是代码的布局。

这个例子很极端,但值得向您展示由 gcc 生成的代码,带有编译器选项-O2

重构上面的代码以去除使用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);
}

使用gcc -S -O2 -std=c++14 编译产生:

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

请注意,优化器已经查看了所有代码,并意识到此代码可以采取的唯一行动(这很重要)是调用函数 emit,参数值为 2000。

教训始终是,人们应该优雅地表达意图(即以一种易于理解和维护的方式)并允许编译器完成其工作,即在最少的时间和/或代码大小内发出实现该意图的代码.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-29
    • 2018-01-26
    • 2020-03-15
    • 2023-03-30
    • 1970-01-01
    • 2013-11-15
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多