À quel point l'aide d'un StringBuilder devient insignifiant ou une surcharge?

StackOverflow https://stackoverflow.com/questions/550702

  •  23-08-2019
  •  | 
  •  

Question

Récemment, je me suis trouvé à l'aide StringBuilder pour tous les concaténations de chaînes, grands et petits, mais dans un récent test de performance, je troqué un collègue de STRINGOUT = string1 + « » chaine2 de style concaténation (utilisé dans une boucle 10000x + avec le StringBuilder étant newed à chaque fois) pour un StringBuilder juste pour voir quelle différence cela ferait dans une concaténation mineure.

J'ai trouvé, sur plusieurs séries de test de performance, le changement était à la fois plus ou moins non significative quel que soit concaténation ou StringBuilder (redisant ce fut pour petits ) concaténations.

À quel point le « newing up » d'un objet StringBuilder nier les avantages de l'utilisation d'un?

Était-ce utile?

La solution

La règle que je suis est -

Utilisez un StringBuilder lorsque le nombre de concaténations est inconnu au moment de la compilation.

Alors, dans votre cas, chaque StringBuilder n'a été quelques fois AJOUT DE, puis d'être mis au rebut. Ce n'est pas vraiment la même chose que quelque chose comme

string s = String.Empty;
for (int i = 0; i < 10000; ++i)
{
    s += "A";
}

Si l'aide d'un StringBuilder améliorerait considérablement les performances parce que vous auriez autrement allouez constamment nouvelle mémoire.

Autres conseils

Je suis sûr que j'ai une autre réponse où je Déposée un à mon article et son résumé, mais on y va à nouveau.

  • utiliser Certainement StringBuilder lorsque vous concaténer dans une boucle non négligeable - surtout si vous ne savez pas sûr (au moment de la compilation) combien d'itérations vous allez faire à travers la boucle. Par exemple, la lecture d'un fichier un caractère à la fois, la construction d'une chaîne que vous allez en utilisant l'opérateur + = est potentiellement suicide de performance.

  • certainement utiliser l'opérateur de concaténation quand vous pouvez (lisiblement) préciser tout ce qui doit être concaténé dans une instruction. (Si vous avez un éventail de choses à concaténer, envisager d'appeler explicitement String.Concat -. Ou String.Join si vous avez besoin d'un delimiter)

  • Ne pas avoir peur de briser littéraux en plusieurs morceaux concaténés - le résultat sera le même. Vous pouvez faciliter la lecture en brisant un long littérale en plusieurs lignes, par exemple, sans nuire à la performance.

  • Si vous avez besoin des résultats intermédiaires de la concaténation pour autre chose que l'alimentation de la prochaine itération de concaténation, StringBuilder ne va pas vous aider. Par exemple, si vous construisez un nom complet d'un prénom et un nom de famille, puis ajouter un troisième élément d'information (le surnom, peut-être) à la fin, vous bénéficiez seulement d'utiliser StringBuilder si vous ne le besoin (prénom + nom) chaîne à d'autres fins (comme nous le faisons dans l'exemple qui crée un objet Person).

  • Si vous avez juste quelques concaténations à faire, et que vous voulez vraiment les faire dans des déclarations séparées, il ne compte pas vraiment dans quel sens vous allez. Quelle façon plus efficace dépendra du nombre de concaténations les tailles de chaîne impliqués, et dans quel ordre ils sont concaténés. Si vous croyez vraiment ce morceau de code pour être un goulot d'étranglement de performance, le profil ou le benchmark dans les deux sens.

Parfois, il est intéressant de regarder :

  

La performance d'une concaténation   fonctionnement d'une chaîne ou   objet StringBuilder dépend de la   souvent une allocation de mémoire se produit. UNE   opération de concaténation de chaîne toujours   alloue de la mémoire, alors qu'un   opération de concaténation StringBuilder   seulement si la mémoire alloue   un tampon d'objet StringBuilder est trop   petite pour accueillir les nouvelles données.   Par conséquent, la classe String est   de préférence pour une concaténation   opération si un nombre fixe de cordes   les objets sont concaténés. dans ce   cas, l'enchaînement particulier   les opérations pourraient même être combinées en   une seule opération par le compilateur. UNE   objet StringBuilder est préférable   une opération de concaténation si un   nombre arbitraire de chaînes sont   concaténé; Par exemple, si une boucle   concatène un nombre aléatoire de   chaînes de saisie de l'utilisateur.

Dans votre exemple, il n'y a qu'une seule concaténation par chaîne de sortie, de sorte que StringBuilder vous ne gagne rien. Vous devez utiliser StringBuilder dans les cas où vous ajoutez aux nombreux même chaîne fois, par exemple:.

stringOut = ...
for(...)
    stringOut += "."
    stringOut += string2

Ma règle de base est simple.

  1. Si vous pouvez raisonnablement écrire une seule expression qui produit la finale, puis utilisez +.
  2. Si vous ne pouvez pas (en raison soit de la taille ou de la variabilité), puis utilisez StringBuilder.

Dans mon expérience, des expressions telles que:

"Id: " + item.id + " name: " + item.name

peut être écrit et compris beaucoup plus facilement que:

StringBuilder sb = new StringBuilder();
sb.append("Id: ").append(item.id);
sb.append(" name: ").append(item.name);

(suivi en utilisant la chaîne de sb où l'expression ci-dessus aurait été écrit), et il fonctionne aussi bien (indice: regardez le code compilé pour voir pourquoi)

Par contre, quand il y a besoin d'accumuler une chaîne au fil du temps (comme le programme court) ou de l'espace (composé de valeurs provenant de différentes parties du code), d'une manière qui est impossible d'écrire en une seule -ligne expression, puis StringBuilder évite la surcharge (temps et la mémoire-barattage) de:

String s = somethingExpression;
...
s += someOtherExpression;
...
s += yetAnotherExpression;
...

De MSDN :

  il classe String est préférable

[T] pour un   opération de concaténation si un fixe   nombre d'objets String sont   concaténer. Dans ce cas, la   opérations individuelles de concaténation   pourrait même être combinés en un seul   opération par le compilateur. UNE   objet StringBuilder est préférable   une opération de concaténation si un   nombre arbitraire de chaînes sont   concaténé; Par exemple, si une boucle   concatène un nombre aléatoire de   chaînes de saisie de l'utilisateur.

Je suppose que la réponse est « ça dépend » - si vous concaténer dans une boucle avec plus d'une poignée d'itérations puis un StringBuilder livrera presque toujours de meilleures performances, mais la seule façon de savoir avec certitude est de profil en fait .

Il y a un article intéressant sur ce sur codage Horror. Jeff a obtenu les résultats suivants pour 100.000 itérations sur un dual core 3,5 GHz Core 2 Duo:

 Simple Concatenation    - 606 ms
 String.Format           - 665 ms
 string.Concat           - 587 ms
 String.Replace          - 979 ms
 StringBuilder           - 588 ms

De Dot Net Perls :

Quand utiliser StringBuilder?

StringBuilder est tout à fait une optimisation, et il offre aucune amélioration logique de chaîne Concat autre que sa mise en œuvre interne. Cela dit, il est essentiel d'utiliser correctement dans vos applications de haute performance et des sites Web.

Parfois, il est correct d'utiliser de petites boucles de 4 ou moins d'itérations avec concats simples cordes. Cependant, en cas de pointe, cela peut être désastreux. Planifiez votre cas de pointe avec StringBuilder.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top