Maison >développement back-end >C++ >Pourquoi le compilateur optimise-t-il les fonctions lambda plus efficacement que les fonctions traditionnelles ?
Optimisation Lambda et fonctions en ligne : l'avantage du compilateur
La déclaration de Nicolai Josuttis selon laquelle les lambdas présentent une optimisation supérieure du compilateur par rapport aux fonctions simples a intrigué de nombreuses personnes. développeurs. En étudiant cette affirmation, nous cherchons à découvrir les raisons sous-jacentes de cet avantage d'optimisation.
Objets de fonction et inlining
Les Lambdas étant des objets de fonction possèdent un avantage clé : les transmettre à Les modèles de fonction déclenchent l'instanciation d'une fonction sur mesure spécifiquement pour ce lambda. Cela permet au compilateur d'intégrer sans effort l'invocation lambda.
En revanche, les fonctions utilisent des pointeurs de fonction lorsqu'elles sont transmises aux modèles de fonction. Traditionnellement, les compilateurs rencontrent des difficultés pour intégrer des appels via des pointeurs de fonction. L'optimisation en ligne n'est réalisable que si la fonction englobante elle-même est intégrée.
Instanciations de modèles : explorer la différence
Pour illustrer cette disparité, considérons le modèle de fonction map :
template <typename Iter, typename F> void map(Iter begin, Iter end, F f) { for (; begin != end; ++begin) *begin = f(*begin); }
L'invoquer avec un lambda :
int a[] = { 1, 2, 3, 4 }; map(begin(a), end(a), [](int n) { return n * 2; });
aboutit à une instanciation personnalisée :
template <> void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) { for (; begin != end; ++begin) *begin = f.operator()(*begin); }
Le compilateur identifie la fonction _some_lambda_type::operator() et peut directement y appeler en ligne. Chaque type lambda distinct provoque une nouvelle instanciation de map, garantissant une optimisation spécifique à lambda.
En revanche, l'invocation de map avec un pointeur de fonction donne l'instanciation suivante :
template <> void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) { for (; begin != end; ++begin) *begin = f(*begin); }
Ici, la fonction le pointeur f pointe vers des adresses variables pour chaque appel de carte, interdisant l'optimisation en ligne. L'appel à map doit être intégré pour que le compilateur résolve f en une fonction spécifique.
Ainsi, le caractère distinctif des lambdas en tant qu'objets de fonction et leur capacité à faciliter les instanciations de modèles confèrent aux compilateurs de plus grandes capacités d'optimisation que celles invoquées par les fonctions traditionnelles. à travers des pointeurs.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!