65 votes

Dois-je retourner std::les chaînes de caractères?

Je suis en train d'utiliser std::string au lieu de char* chaque fois que possible, mais j'ai des soucis je peut dégrader les performances de trop. Est-ce un bon moyen de retour de chaînes (pas de contrôle d'erreur pour des raisons de concision)?

std::string linux_settings_provider::get_home_folder() {
    return std::string(getenv("HOME"));
}

Aussi, une question: lors de l'acceptation des chaînes en tant que paramètres, je devrais les recevoir comme const std::string& ou const char*?

Merci.

63voto

duffymo Points 188155

De retour de la chaîne.

Je pense que le mieux l'abstraction en vaut la peine. Jusqu'à ce que vous pouvez mesurer un rendement significatif de la différence, je dirais que c'est un micro-optimisation, qui n'existe que dans votre imagination.

Il a fallu de nombreuses années pour obtenir une bonne abstraction des chaînes de caractères en C++. Je ne crois pas que Bjarne Stroustroup, si célèbre pour son conservateur "ne payez que pour ce que vous utilisez" dictum, aurait permis à un évident performance killer dans la langue. Niveau d'abstraction plus est bonne.

14voto

Steve Jessop Points 166970

De retour de la chaîne, comme tout le monde le dit.

lors de l'acceptation des chaînes en tant que paramètres, je devrais les recevoir comme const std::string& ou const char*?

Je dirais de prendre toute const paramètres par référence, sauf s'ils sont assez légers pour prendre de la valeur, ou dans les rares cas où vous avez besoin d'un pointeur null à une entrée valide sens "none of the above". Cette politique n'est pas spécifique à cordes.

Non-const paramètres de référence sont discutables, car à partir du code d'appel (sans une bonne IDE), vous ne pouvez pas voir immédiatement s'ils sont passés par valeur ou par référence, et la différence est importante. Ainsi, le code peut-être pas clair. Pour const params, qui ne s'applique pas. Les personnes lisant le code appelant peut généralement présumer que ce n'est pas leur problème, donc ils vont parfois uniquement besoin de vérifier la signature.

Dans le cas où vous allez prendre une copie de l'argument de la fonction, de votre politique générale devrait être de prendre l'argument par valeur. Alors que vous avez déjà une copie, vous pouvez utiliser, et si vous l'avez copié dans un lieu particulier (comme un membre de données), vous pouvez alors le déplacer (en C++11) ou de swap (en C++03) pour l'obtenir. Cela donne le compilateur la meilleure opportunité pour optimiser les cas où l'appelant passe un objet temporaire.

Pour string en particulier, ce qui couvre le cas où votre fonction prend un std::string en valeur, et l'appelant indique que l'argument de l'expression d'un littéral de chaîne ou un char* pointant vers un nul de terminaison de chaîne. Si vous avez pris un const std::string& et copié dans la fonction, ce qui aurait pour conséquence la construction de deux chaînes de caractères.

12voto

jskinner Points 371

Le coût de la copie des chaînes par valeur varie en fonction de la STL de mise en œuvre vous travaillez:

  • std::string sous MSVC utilise la chaîne de l'optimisation, de sorte que les chaînes courtes (< 16 caractères iirc) ne nécessitent pas d'allocation de mémoire (ils sont stockés dans le std::string lui-même), tandis que les plus longs nécessitent une allocation de tas à chaque fois que la copie de la chaîne.

  • std::string sous GCC utilise une référence compté mise en œuvre: lors de la construction d'un std::string à partir d'un char*, un tas de répartition est effectuée à chaque fois, mais lors du passage par valeur à une fonction, un compteur de référence est tout simplement incrémenté, en évitant l'allocation de la mémoire.

En général, vous êtes mieux de simplement oublier l'au-dessus et en retournant std::les chaînes de valeur, si ce n'est des milliers de fois par seconde.

re: passage de paramètres, gardez à l'esprit qu'il y a un coût d'aller de char*->std::string, mais pas d'aller de std::string->char*. En général, cela signifie que vous êtes mieux d'accepter un const référence à une std::string. Cependant, la meilleure justification pour l'acceptation d'un const std::string& comme argument, c'est qu'alors le destinataire de l'appel ne doit pas avoir plus de code pour vérifier vs null.

10voto

kkaploon Points 968

Semble être une bonne idée.

Si ce n'est pas une partie d'un logiciel realtime (comme un jeu), mais une application régulière, vous devriez être plus que bien.

Rappelez-vous, "l'optimisation Prématurée est la racine de tous les maux"

5voto

Kirill V. Lyadvinsky Points 47627

Dans votre cas, la Valeur de Retour de l'Optimisation prendra place pour std::string ne seront pas copiés.

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