49 votes

Coût des paramètres par défaut dans le CMD

Je suis tombé sur un exemple de "Effective C " dans un environnement intégré" par Scott Meyers où deux façons d'utiliser les paramètres par défaut ont été décrites: l'une qui a été décrite comme coûteuse et l'autre comme une meilleure option.

Je manque l'explication de pourquoi la première option pourrait être plus coûteuse par rapport à l'autre.

57voto

Angew Points 53063

Dans le premier, un temporaire est initialisé à partir du littéral chaque fois que ** la fonction est appelée sans argument.

Dans le second cas, l'objet `` est initialisé une fois (par fichier source) et simplement utilisé sur chaque appel.

19voto

Yakk Points 31636
void doThat(const std::string& name = "Unnamed"); // Bad

C'est "mauvais" dans un nouveau std::string avec le contenu de l' "Unnamed" est créé chaque fois qu' doThat() est appelé.

Je dis "mauvais" et pas mauvais parce que la petite optimisation de la chaîne dans chaque compilateur C++ j'ai utilisé à la place de l' "Unnamed" données au sein de l'entreprise std::string créé sur le site d'appel et de ne pas allouer de stockage pour elle. Ainsi, dans cet spécifique cas, il y a peu de coût de la temporaire de l'argument. La norme n'impose pas de la petite optimisation de la chaîne, mais il est explicitement conçu pour permettre à, et à chaque bibliothèque standard en usage actuellement dans l'implémente.

Une longue chaîne de provoquer une allocation; la petite optimisation de la chaîne travaille sur de courtes chaînes de caractères seulement. Les Allocations sont chers, si vous utilisez la règle de base qu'une seule allocation est de+ de 1000 fois plus cher que d'habitude instruction (plusieurs microsecondes!), vous ne serez pas loin.

const std::string defaultName = "Unnamed";
void doThat(const std::string& name = defaultName); // Better

Ici, nous créons un mondial defaultName avec le contenu de l' "Unnamed". Il est créé à l'initialisation statique de temps. Il y a certains risques; s' doThat est appelée à l'initialisation statique ou de la destruction du temps (avant ou après l' main exécuté), il peut être invoqué avec une unconstructed defaultName ou qui a déjà été détruit.

D'autre part, il n'y a pas de risque que par appel d'allocation de mémoire va se produire ici.


Maintenant, la bonne solution moderne du est:

void doThat(std::string_view name = "Unnamed"); // Best

ce qui n'est pas allouer même si la chaîne est longue; elle n'a même pas de copier la chaîne! En plus de cela, dans 999/1000 cas, c'est une baisse-dans le remplacement pour le vieux - doThat API et il peut même améliorer les performances lorsque vous faire passer des données en doThat et ne pas compter sur l'argument par défaut.

À ce stade, de soutien dans l'embarqué peut-être pas là, mais dans certains cas, il pourrait l'être prochainement. Et la chaîne de vue est d'une assez grande augmentation de la performance qu'il existe une multitude de types similaires déjà dans la nature qui font la même chose.

Mais la leçon reste; ne pas procéder à de coûteuses opérations dans des arguments par défaut. Et de l'allocation peut être coûteux dans certains contextes (en particulier le monde embarqué).

3voto

tobi303 Points 2932

Peut-être que j'ai mal interpréter "coûteux" (pour l'interprétation "correcte" de voir les autres réponses), mais une chose à considérer avec les paramètres par défaut c'est qu'ils ne sont pas à l'échelle dans des situations comme ça:

void foo(int x = 0);
void bar(int x = 0) { foo(x); }

Cela devient une source d'erreurs cauchemar une fois que vous ajoutez plus de nidification, car la valeur par défaut doit être répété à plusieurs endroits (ie coûteux dans le sens qu'un petit changement doit changer de différents endroits dans le code). Le meilleur moyen d'éviter cela, c'est comme dans votre exemple:

const int foo_default = 0;
void foo(int x = foo_default);
void bar(int x = foo_default) { foo(x); } // no need to repeat the value here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X