Par exemple, j'ai le code suivant:
auto z = [](int x) -> int {
if (x > 0) {
switch (x) {
case 2: return 5;
case 3: return 6;
default: return 1;
}
}
return 0;
};
Et plus tard, j'appelle cela plusieurs fois. Dans le code asm, je vois des appels externes avec lambda .... quelque chose ... Cela devient difficile à lire et je pense que cela peut également entraîner des performances. Alors peut-être que je gagne en méta-programmation mais est-ce que je perds en débogage asm et en performances? Dois-je éviter les fonctionnalités du langage moderne, les macros et autres aspects de la méta-programmation pour être sûr en termes de performances et de simplicité de débogage?
if
est complètement redondant dans l'exemple de code, et bien que le compilateur le détecte probablement, il n'y a aucune raison de tenter une mauvaise prédiction de branche.Réponses:
Non , pas lorsque vous écrivez votre code la première fois et que vous ne souffrez d'aucun problème de performance réel et mesurable. Pour la plupart des tâches, c'est le cas standard. Penser trop tôt à l'optimisation est appelé "optimisation prématurée", et il y a de bonnes raisons pour que D. Knuth appelle cela "la racine de tout mal" .
Oui , lorsque vous mesurez un goulot d'étranglement des performances réel et prouvable, et que vous identifiez cette construction lambda spécifique comme la cause première. Dans ce cas, il peut être judicieux de se souvenir de la "loi des abstractions qui fuient" de Joel Spolsky et de réfléchir à ce qui pourrait se produire au niveau de l'asm. Mais attention, vous serez peut-être étonné de voir à quel point l'augmentation des performances sera faible lorsque vous remplacerez une construction lambda par une construction de langage "pas si moderne" (du moins, lorsque vous utilisez un compilateur C ++ décent).
la source
Le choix entre lambda et functor-class est un compromis.
Le gain de lambda est principalement syntaxique, en minimisant la quantité de passe-partout et en permettant l'écriture de code conceptuel en ligne, à l'intérieur de la fonction qui va l'utiliser (immédiatement ou plus tard).
En termes de performances, ce n'est pas pire qu'une classe functor , qui est une structure ou une classe C ++ qui contient une seule "méthode". En fait, les compilateurs ne traitent pas lambda différemment d'une classe de foncteurs générée par le compilateur derrière la scène.
Dans votre exemple de code, en termes de performances, il n'est pas différent d'un appel de fonction, car cette classe de fonctor n'a aucun état (car elle a une clause de capture vide), ne nécessitant ainsi aucune allocation, constructeur ou destruction.
Le débogage de tout code C ++ non trivial à l'aide d'un désassembleur a toujours été une tâche difficile. Cela est vrai avec ou sans utilisation de lambda. Cela est dû à l'optimisation sophistiquée du code par le compilateur C ++ qui a entraîné la réorganisation, l'entrelacement et l'élimination du code mort.
L'aspect de manipulation de nom est quelque peu désagréable, et le support du débogueur pour lambda est encore à ses balbutiements . On ne peut qu'espérer que le support du débogueur s'améliorera avec le temps.
Actuellement, la meilleure façon de déboguer du code lambda est d'utiliser un débogueur qui prend en charge la définition de points d'arrêt au niveau du code source, c'est-à-dire en spécifiant le nom du fichier source et le numéro de ligne.
la source
Pour ajouter à la réponse de @DocBrown, rappelez-vous que de nos jours, les CPU sont bon marché mais la main-d'œuvre est chère.
Dans le coût global d'un programme, le matériel est généralement insignifiant par rapport au coût de maintenance, qui est de loin la partie la plus chère d'un projet typique (encore plus que son développement).
Par conséquent, votre code doit optimiser la maintenance avant tout, sauf lorsque les performances sont critiques (et même dans ce cas, la maintenance doit être prise en compte).
la source