Lambda 函数优化
Nicolai Josuttis 在《C 标准库》中声称,编译器对 lambda 的优化比普通函数更好。这就提出了为什么会出现这种情况的问题。
内联优化
人们可能会认为内联优化不会区分 lambda 和普通函数。然而,关键的区别在于 lambda 作为函数对象的性质。
函数对象与函数指针
当 lambda 传递给函数模板时,它专门为该对象创建一个新函数,从而导致一个简单的内联函数调用。相反,普通函数传递函数指针,这通常会导致内联优化出现问题。理论上,编译器可以内联此类调用,但前提是周围的函数也内联。
示例
考虑一个函数模板映射,它采用迭代器和函数对象作为参数:
template <typename Iter, typename F> void map(Iter begin, Iter end, F f) { for (; begin != end; ++begin) *begin = f(*begin); }
使用以下参数调用此模板lambda:
int a[] = { 1, 2, 3, 4 }; map(begin(a), end(a), [](int n) { return n * 2; });
创建函数的新实例化:
template <> void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) { for (; begin != end; ++begin) *begin = f.operator()(*begin); }
编译器可以轻松内联调用 lambda 的运算符()。
但是,当使用函数指针:
int a[] = { 1, 2, 3, 4 }; map(begin(a), end(a), &my_function);
结果实例化变为:
template <> void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) { for (; begin != end; ++begin) *begin = f(*begin); }
这里,f对于每次对map的调用都指向不同的地址,禁止内联优化,除非周围对map的调用也内联。
因此,优化优势lambda 源于它们创建函数对象的能力,这些函数对象支持简单的内联功能。
以上是为什么编译器对 Lambda 的优化比普通函数更好?的详细内容。更多信息请关注PHP中文网其他相关文章!