Maison  >  Article  >  développement back-end  >  Les Lambdas peuvent-ils être mieux optimisés que les fonctions simples par les compilateurs ?

Les Lambdas peuvent-ils être mieux optimisés que les fonctions simples par les compilateurs ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-19 18:33:03201parcourir

Can Lambdas Be Optimized Better Than Plain Functions By Compilers?

Optimisations du compilateur pour Lambdas vs. Plain Functions

Dans son livre, "The C Standard Library (Second Edition)", affirme Nicolai Josuttis que les lambdas peuvent être mieux optimisés par le compilateur que les fonctions simples. Cela peut sembler contre-intuitif, étant donné que les fonctions lambda et simples peuvent être intégrées. Cependant, il existe une différence subtile entre les deux qui permet de meilleures optimisations dans le cas des lambdas.

La différence : objets de fonction et pointeurs de fonction

Les lambdas sont des objets de fonction, tandis que les fonctions simples sont essentiellement des pointeurs de fonction. Lors du passage d'un lambda à un modèle de fonction, une nouvelle fonction spécifiquement pour cet objet est instanciée. Cela permet au compilateur d'intégrer de manière triviale l'appel lambda.

En revanche, passer une fonction simple à un modèle de fonction entraîne la transmission d'un pointeur de fonction. Les compilateurs ont toujours eu du mal à intégrer les appels via des pointeurs de fonction. Bien qu'ils puissent théoriquement être intégrés, cela ne se produit que si la fonction environnante est également intégrée.

Un exemple

Considérez le modèle de fonction suivant :

template <typename Iter, typename F>
void map(Iter begin, Iter end, F f) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}

L'appeler avec un lambda :

int a[] = { 1, 2, 3, 4 };
map(begin(a), end(a), [](int n) { return n * 2; });

Se traduira par une instanciation unique :

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 peut identifier l'opérateur du lambda() et y faire des appels trivialement en ligne.

Mais lorsqu'il est appelé avec un pointeur de fonction :

map(begin(a), end(a), &multiply_by_two);

L'instanciation devient :

template <>
void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}

Ici, f fait référence à différentes fonctions à chaque fois que map est appelée, empêchant le Le compilateur ne peut pas intégrer d'appels à moins que la carte elle-même ne soit intégrée.

Conclusion

Le type unique de lambdas en tant qu'objets de fonction permet aux compilateurs de créer des instanciations de fonctions spécifiques et d'intégrer de manière transparente leurs appels. Cette capacité d'optimisation améliorée distingue les lambdas des fonctions simples, ce qui en fait un choix privilégié pour améliorer les performances et l'efficacité du code.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn