[英]C++11 Performance: Lambda inlining vs Function template specialization
我的问题是在此基础上扩展: 为什么与普通函数相比,编译器可以更好地优化lambda?
重申一下,得出的结论是,lambda创建了不同的专业化标准,编译器可以轻松地对其进行内联,而函数指针则不那么容易内联化,因为一组函数原型只有一个专业化标准。 考虑到这一点,函数指针模板会像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);
}
因此,如果我可以根据绩效等级对其进行排名,则:
operatorFuncTemplate
> = operate<LAMBDA>
>> = operate<FUNCTIONPTR>
在非平凡的例子中,是否存在这种关系失败的情况?
如果编译器可以跟踪“此函数指针指向该函数”,则编译器可以通过函数指针内联该调用。
有时编译器可以做到这一点。 有时他们不能。
除非您将lambda存储在函数指针, std::function
或类似的类型擦除包装器中,否则在调用lambda时,编译器会知道lambda的类型,因此会知道lambda的主体。 编译器可以轻松地内联函数调用。
使用函数模板没有任何改变,除非参数是像constexpr
一样的函数非类型模板参数:
template <int func(int, int)>
这是一个例子。 在此,保证了函数主体中的函数模板在编译时是已知的。
但是,将该func
传递到其他任何地方,编译器可能会无法对其进行跟踪。
无论如何,任何速度差异都将高度依赖于上下文。 有时,由内联lambda引起的较大的二进制大小会比无法内联函数指针的情况导致更慢的速度,因此性能可能会反过来。
像您要提出的任何普遍主张有时都会出错。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.