Lambda Optimization and Inline Functions: The Compiler's Advantage
Nicolai Josuttis' statement that lambdas exhibit superior compiler optimization compared to plain functions has intrigued many developers. Investigating this claim, we seek to unravel the underlying reasons behind this optimization advantage.
Function Objects and Inlining
Lambdas being function objects possess a key advantage: passing them to function templates triggers the instantiation of a tailored function specifically for that lambda. This allows the compiler to effortlessly inline the lambda invocation.
In contrast, functions employ function pointers when passed to function templates. Traditionally, compilers encounter challenges inlining calls through function pointers. Inline optimization is feasible only if the enclosing function itself is inlined.
Template Instantiations: Exploring the Difference
To illustrate this disparity, consider the map function template:
template <typename Iter, typename F> void map(Iter begin, Iter end, F f) { for (; begin != end; ++begin) *begin = f(*begin); }
Invoking it with a lambda:
int a[] = { 1, 2, 3, 4 }; map(begin(a), end(a), [](int n) { return n * 2; });
results in a customized instantiation:
template <> void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) { for (; begin != end; ++begin) *begin = f.operator()(*begin); }
The compiler identifies the _some_lambda_type::operator() function and can directly inline calls to it. Every distinct lambda type prompts a new instantiation of map, guaranteeing lambda-specific optimization.
In contrast, invoking map with a function pointer yields the following instantiation:
template <> void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) { for (; begin != end; ++begin) *begin = f(*begin); }
Here, the function pointer f points to varying addresses for each map call, prohibiting inline optimization. The call to map must be inlined for the compiler to resolve f to a specific function.
Thus, the distinctiveness of lambdas as function objects and their ability to facilitate template instantiations empower compilers with greater optimization capabilities than traditional functions invoke through pointers.
The above is the detailed content of Why does the compiler optimize lambda functions more effectively than traditional functions?. For more information, please follow other related articles on the PHP Chinese website!