J’ai un petit morceau de code qui est l’analyse d’une valeur d’index pour déterminer une entrée de cellule dans Excel. Il m’a fait penser...
Quelle est la différence entre
et
Est une « meilleure » que l’autre ? Et pourquoi ?
J’ai un petit morceau de code qui est l’analyse d’une valeur d’index pour déterminer une entrée de cellule dans Excel. Il m’a fait penser...
Quelle est la différence entre
et
Est une « meilleure » que l’autre ? Et pourquoi ?
Ma préférence initiale (venant d'un C++ arrière-plan) a été pour la Chaîne.Format. J'ai abandonné plus tard pour les raisons suivantes:
- La concaténation de chaîne autorise les valeurs null, String.Format
ne le sont pas. L'écriture "s1 + null + s2
" ne rompt pas, il vient de traite de la valeur null comme une Chaîne de caractères.Vide. Eh bien, cela dépend de votre scénario spécifique - il y a des cas où vous souhaitez une erreur au lieu de l'ignorer silencieusement null Prénom. Cependant, même dans cette situation, je préfère personnellement la vérification pour les valeurs null moi-même et en jetant les erreurs spécifiques au lieu de la norme ArgumentNullException je reçois de la Chaîne.Format.
C'est l'idée .NET compilateur est assez intelligent pour convertir ce morceau de code:
public static string Test(string s1, int i2, int i3, int i4,
string s5, string s6, float f7, float f8)
{
return s1 + " " + i2 + i3 + i4 + " ddd " + s5 + s6 + f7 + f8;
}
pour cela:
public static string Test(string s1, int i2, int i3, int i4,
string s5, string s6, float f7, float f8)
{
return string.Concat(new object[] { s1, " ", i2, i3, i4,
" ddd ", s5, s6, f7, f8 });
}
Ce qui se passe sous le capot de la Chaîne.Concat est facile à deviner (utilisation du Réflecteur). Les objets dans le tableau est converti à leur chaîne via ToString(). Ensuite, la longueur totale est calculée et qu'une chaîne allouée (avec la longueur totale). Enfin, chaque chaîne est copié dans la chaîne résultante via wstrcpy dans certains dangereux morceau de code.
Raisons String.Concat
est plus rapide? Eh bien, nous pouvons tous avoir un coup d'oeil ce qu' String.Format
- vous serez surpris par la quantité de code nécessaire au processus de la chaîne de format. Sur le dessus de cela (j'ai vu des commentaires au sujet de la consommation de mémoire), String.Format
utilise un StringBuilder en interne. Voici comment:
StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
Ainsi, pour chaque argument passé, il se réserve de 8 caractères. Si l'argument est une valeur d'un seul chiffre, alors tant pis, nous avons un espace gaspillé. Si l'argument est un objet personnalisé de retour texte très long sur ToString()
, alors il pourrait y avoir encore quelques réaffectation nécessaire (le pire scénario, bien sûr).
Par rapport à cela, la concaténation uniquement les déchets de l'espace de l'objet array (pas trop, en tenant compte, c'est un tableau de références). Il n'y a pas d'analyse pour les spécificateurs de format et pas d'intermédiaire StringBuilder. Le boxing/unboxing de surcharge est présente dans les deux méthodes.
La seule raison pour laquelle j'irais pour la Chaîne.Le Format est lorsque la localisation est impliqué. Mettre chaînes de formatage de ressources permet de prendre en charge différentes langues sans vous embêter avec le code (penser à des scénarios où les valeurs mises en forme la modification de la commande en fonction de la langue, c'est à dire "après {0} heures et {1} minutes" peut paraître très différente en Japonais :).
Pour résumer mon premier (et très long) post:
ToString()
appelsToString()
des appels vous-même pour éviter de boxe (je suis un peu biaisé vers plus de lisibilité) - même en tant que première option dans votre questionString.Format()
a un bord.Pour être honnête, je pense que la première version est plus simple - même si j’ai de simplifierait :
Je soupçonne que d’autre réponses peuvent parler de la baisse de performance, mais pour être honnête, ça va être un minimum s’il est présent à tous - et cette version de concaténation n’a pas besoin d’analyser la chaîne de format.
Chaînes de format sont parfaits pour des fins de localisation etc., mais dans un cas comme cette concaténation est plus simple et fonctionne aussi bien.
Je pense que ce lien MSDN est un résumé raisonnable. Jon Skeet a également une entrée de blog intéressant sur le sujet
Je pense que la première option est plus lisible et qui doit être votre principale préoccupation.
xlsSheet.Write("C" + rowIndex.ToString(), null, title);
chaîne de caractères.Format utilise un StringBuilder sous le capot (vérifier avec réflecteur) afin de ne pas avantage, sauf si vous faites une quantité importante de concaténation. Il sera plus lent pour votre scénario, mais la réalité est la micro-optimisation de la performance décision est inapproprié plupart du temps, et vous devriez vraiment se concentrer sur la lisibilité de votre code, sauf si vous êtes dans une boucle.
De toute façon, écrire pour des raisons de lisibilité d'abord et ensuite utiliser un profileur de performance afin d'identifier vos points chauds si vous pensez vraiment que vous avez des problèmes de rendement.
Pour un cas simple où c'est une simple concaténation, j'ai l'impression que ça n'en vaut pas la complexité de l' string.Format
(et je n'ai pas testé, mais je suppose que pour un cas simple comme ça, string.Format
peut - être un peu plus lent, ce qui avec la chaîne de format d'analyse et de tous). Comme Jon Skeet, je préfère ne pas appeler explicitement .ToString()
, depuis qui sera fait de façon implicite par l' string.Concat(string, object)
de surcharge, et je pense que le code est plus propre et d'apparence plus facile à lire sans elle.
Mais pour plus de quelques enchaînements (combien est subjectif), je préfère largement string.Format
. À un certain point, je pense qu'à la fois la lisibilité et la performance de souffrir inutilement avec la concaténation.
Si il y a de nombreux paramètres à la chaîne de format (encore une fois, "beaucoup" est subjectif), je préfère inclure commenté indices sur le remplacement des arguments, de peur que je perds la trace de valeur pour le paramètre. Un exemple artificiel:
Console.WriteLine(
"Dear {0} {1},\n\n" +
"Our records indicate that your {2}, \"{3}\", is due for {4} {5} shots.\n" +
"Please call our office at 1-900-382-5633 to make an appointment.\n\n" +
"Thank you,\n" +
"Eastern Vetinary",
/*0*/client.Title,
/*1*/client.LastName,
/*2*/client.Pet.Animal,
/*3*/client.Pet.Name,
/*4*/client.Pet.Gender == Gender.Male ? "his" : "her",
/*5*/client.Pet.Schedule[0]
);
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.