C++ 11性能:Lambda内联与函数模板特化

Mic*_*hoi 3 c++ performance lambda templates inline

我的问题是扩展这个:为什么lambdas可以通过编译器比普通函数更好地优化?

重申一下,结论是lambdas创建了不同的特化,编译器可以简单地内联,而函数指针不像内联那么容易,因为对于一组函数原型只有一个特化.考虑到这一点,将函数指针模板作为快速/更快的lambdas?

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }

template <class F>
int operate(int a, int b, F func)
{
    return func(a, b);
}

template <int func(int, int)>
int operateFuncTemplate(int a, int b)
{
    return func(a, b);
}

int main()
{
    // hard to inline (can't determine statically if operate's f is add or sub since its just a function pointer)
    auto addWithFuncP = operate(1, 2, add);
    auto subWithFuncP = operate(1, 2, sub);

    // easy to inline (lambdas are unique so 2 specializations made, each easy to inline)
    auto addWithLamda = operate(1, 2, [](int a, int b) { return a + b; });
    auto subWithLamda = operate(1, 2, [](int a, int b) { return a - b; });

    // also easy to inline? specialization means there are 2 made, instead of just 1 function definition with indirection?
    auto addWithFuncT = operateFuncTemplate<add>(1, 2);
    auto subWithFuncT = operateFuncTemplate<sub>(1, 2);
}
Run Code Online (Sandbox Code Playgroud)

因此,如果我能按性能等级对这些进行排名,那么:

operatorFuncTemplate> = operate<LAMBDA>> =operate<FUNCTIONPTR>

是否存在这种关系在非平凡的例子中失败的情况?

Yak*_*ont 7

如果编译器可以跟踪"此函数指针指向此函数",则编译器可以通过函数指针内联调用.

有时编译器可以做到这一点.有时他们不能.

除非将lambda存储在函数指针 std::function或类似的类型擦除包装器中,否则调用lambda的位置的编译器知道lambda的类型,因此知道lambda的主体.编译器可以简单地内联函数调用.

使用函数模板没有任何改变,除非参数constexpr类似于函数非类型模板参数:

template <int func(int, int)>
Run Code Online (Sandbox Code Playgroud)

这就是一个例子.这里,函数体中的函数模板保证在编译时是已知的.

func然而,在其他任何地方传递,编译器可能会丢失它.

在任何情况下,任何速度差异都将高度依赖于上下文.有时,内联lambda引起的较大二进制大小会导致比无法内联函数指针更慢的速度,因此性能可以反过来.

像你试图做出的任何普遍要求有时会出错.