Oui, la différence de performances est significative. Consultez l'article de la base de connaissances « Comment améliorer les performances de concaténation de chaînes dans Visual C # ».
J'ai toujours essayé de coder pour plus de clarté, puis d'optimiser les performances plus tard. C'est beaucoup plus facile que de faire l'inverse! Cependant, après avoir vu l'énorme différence de performances dans mes applications entre les deux, j'y réfléchis maintenant un peu plus attentivement.
Heureusement, il est relativement simple d'exécuter une analyse des performances sur votre code pour voir où vous passez du temps, puis de le modifier pour l'utiliser StringBuilder
si nécessaire.
Pour clarifier ce que Gillian a dit à propos de 4 cordes, si vous avez quelque chose comme ça:
alors ce serait plus rapide en utilisant des chaînes et l'opérateur plus. En effet (comme Java, comme le souligne Eric), il utilise automatiquement StringBuilder en interne (en fait, il utilise une primitive que StringBuilder utilise également)
Cependant, si ce que vous faites est plus proche de:
Ensuite, vous devez utiliser explicitement un StringBuilder. .Net ne crée pas automatiquement un StringBuilder ici, car ce serait inutile. À la fin de chaque ligne, "a" doit être une chaîne (immuable), il devrait donc créer et supprimer un StringBuilder sur chaque ligne. Pour la vitesse, vous devez utiliser le même StringBuilder jusqu'à ce que vous ayez fini de construire:
la source
a
est une variable locale et que l'objet auquel elle fait référence n'a pas été affecté à une autre variable (qui pourrait être accessible à un autre thread), un bon optimiseur pourrait déterminer que aucun autre codea
n'est accessible par cette séquence de lignes; seule la valeur finale desa
matières. Il pourrait donc traiter ces trois lignes de code comme si elles avaient été écritesa = b + c + d;
.StringBuilder est préférable SI vous faites plusieurs boucles ou fourchettes dans votre passe de code ... cependant, pour des performances PURE, si vous pouvez vous en sortir avec une déclaration de chaîne SINGLE , alors c'est beaucoup plus performant.
Par exemple:
est plus performant que
Dans ce cas, StringBuild pourrait être considéré comme plus maintenable, mais n'est pas plus performant que la déclaration de chaîne unique.
9 fois sur 10 cependant ... utilisez le générateur de chaînes.
Sur une note latérale: string + var est également plus performant que l'approche string.Format (généralement) qui utilise un StringBuilder en interne (en cas de doute ... vérifiez le réflecteur!)
la source
Un exemple simple pour démontrer la différence de vitesse lors de l'utilisation de la
String
concaténation vsStringBuilder
:Résultat:
Résultat:
En conséquence, la première itération a pris 15423 ms tandis que la deuxième itération utilisant a
StringBuilder
pris 10 ms.Il me semble que l'utilisation
StringBuilder
est plus rapide, beaucoup plus rapide.la source
Cette référence montre que la concaténation régulière est plus rapide lors de la combinaison de 3 chaînes ou moins.
http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/
StringBuilder peut améliorer considérablement l'utilisation de la mémoire, en particulier dans le cas où vous ajoutez 500 chaînes ensemble.
Prenons l'exemple suivant:
Que se passe-t-il en mémoire? Les chaînes suivantes sont créées:
En ajoutant ces cinq nombres à la fin de la chaîne, nous avons créé 13 objets chaîne! Et 12 d'entre eux étaient inutiles! Hou la la!
StringBuilder résout ce problème. Ce n'est pas une "chaîne modifiable" comme nous l'entendons souvent ( toutes les chaînes en .NET sont immuables ). Il fonctionne en gardant un tampon interne, un tableau de caractères. Appeler Append () ou AppendLine () ajoute la chaîne à l'espace vide à la fin du tableau char; si le tableau est trop petit, il crée un nouveau tableau plus grand et y copie le tampon. Ainsi, dans l'exemple ci-dessus, StringBuilder peut n'avoir besoin que d'un seul tableau pour contenir les 5 ajouts à la chaîne, selon la taille de son tampon. Vous pouvez indiquer à StringBuilder la taille de son tampon dans le constructeur.
la source
i.ToString()
. Donc, avec StringBuilder, vous devez toujours créer 6 + 1 chaînes; il a réduit la création de 13 chaînes à la création de 7 chaînes. Mais ce n'est toujours pas la bonne façon de voir les choses; la création des six chaînes de nombres n'est pas pertinente. Conclusion: vous n'auriez tout simplement pas dû mentionner les six chaînes créées pari.ToString()
; ils ne font pas partie de la comparaison d'efficacité.String Vs String Builder:
Première chose que vous devez savoir dans quelle assemblée vit ces deux classes?
Alors,
la chaîne est présente dans l'
System
espace de noms.et
StringBuilder est présent dans l'
System.Text
espace de noms.Pour la déclaration de chaîne :
Vous devez inclure l'
System
espace de noms. quelque chose comme ça.Using System;
et
Pour la déclaration StringBuilder :
Vous devez inclure l'
System.text
espace de noms. quelque chose comme ça.Using System.text;
Maintenant, venez la vraie question.
Quelle est la différence entre string et StringBuilder ?
La principale différence entre ces deux est que:
la chaîne est immuable.
et
StringBuilder est mutable.
Voyons maintenant la différence entre immuable et mutable
Mutable:: signifie modifiable.
Immuable:: signifie Non modifiable.
Par exemple:
Donc, dans ce cas, nous allons changer le même objet 5 fois.
Donc, la question évidente est que! Qu'est-ce qui se passe réellement sous le capot, lorsque nous changeons la même chaîne 5 fois.
C'est ce qui se passe lorsque nous changeons la même chaîne 5 fois.
regardons la figure.
Explication:
Lorsque nous initialisons pour la première fois cette variable "nom" en "Rehan", c'est-à
string name = "Rehan"
- dire que cette variable est créée sur la pile "nom" et pointe vers cette valeur "Rehan". après l'exécution de cette ligne: "nom = nom +" Shah ". la variable de référence ne pointe plus sur cet objet" Rehan ", elle pointe maintenant sur" Shah "et ainsi de suite.Il en
string
est de même immuable signifiant qu'une fois que nous créons l'objet dans la mémoire, nous ne pouvons pas les changer.Ainsi, lorsque nous concaténons la
name
variable, l'objet précédent reste là dans la mémoire et un autre nouvel objet chaîne est créé ...Donc, d'après la figure ci-dessus, nous avons cinq objets, les quatre objets sont jetés, ils ne sont pas utilisés du tout. Ils restent en mémoire et ils occupent la quantité de mémoire. "Garbage Collector" est responsable de ce nettoyage si propre que les ressources de la mémoire.
Donc, en cas de chaîne, à tout moment, lorsque nous manipulons la chaîne encore et encore, nous avons de nombreux objets créés et y restons en mémoire.
Voici donc l'histoire de la chaîne Variable.
Regardons maintenant vers StringBuilder Object. Par exemple:
Donc, dans ce cas, nous allons changer le même objet 5 fois.
Donc, la question évidente est que! Ce qui se passe réellement sous le capot, lorsque nous changeons le même StringBuilder 5 fois.
C'est ce qui se passe lorsque nous changeons le même StringBuilder 5 fois.
regardons la figure.
Explication: dans le cas d'un objet StringBuilder. vous n'obtiendrez pas le nouvel objet. Le même objet sera changé en mémoire donc même si vous changez d'objet et disons 10 000 fois nous n'aurons toujours qu'un seul objet stringBuilder.
Vous n'avez pas beaucoup d'objets garbage ou d'objets stringBuilder non référencés parce que cela peut être changé. Il est mutable ce qui signifie qu'il change au fil du temps?
Différences:
la source
Oui,
StringBuilder
donne de meilleures performances tout en effectuant des opérations répétées sur une chaîne. C'est parce que toutes les modifications sont apportées à une seule instance, ce qui permet de gagner beaucoup de temps au lieu de créer une nouvelle instance commeString
.String Vs Stringbuilder
String
System
espace de nomsStringBuilder
(chaîne mutable)System.Text
espace de nomsla source
StringBuilder réduit le nombre d'allocations et d'affectations, au prix d'une mémoire supplémentaire utilisée. Utilisé correctement, il peut supprimer complètement la nécessité pour le compilateur d'allouer de plus en plus de chaînes jusqu'à ce que le résultat soit trouvé.
contre.
la source
Source: MSDN
la source
StringBuilder
est préférable pour construire une chaîne à partir de nombreuses valeurs non constantes.Si vous créez une chaîne à partir d'un grand nombre de valeurs constantes, telles que plusieurs lignes de valeurs dans un document HTML ou XML ou d'autres morceaux de texte, vous pouvez vous contenter d'ajouter simplement à la même chaîne, car presque tous les compilateurs le font "pliage constant", un processus de réduction de l'arbre d'analyse lorsque vous avez un tas de manipulation constante (il est également utilisé lorsque vous écrivez quelque chose comme
int minutesPerYear = 24 * 365 * 60
). Et pour les cas simples avec des valeurs non constantes ajoutées les unes aux autres, le compilateur .NET réduira votre code à quelque chose de similaire à ce qui seStringBuilder
passe.Mais lorsque votre ajout ne peut pas être réduit à quelque chose de plus simple par le compilateur, vous aurez besoin d'un
StringBuilder
. Comme le souligne fizch, cela est plus susceptible de se produire à l'intérieur d'une boucle.la source
Je crois que StringBuilder est plus rapide si vous avez plus de 4 chaînes que vous devez ajouter ensemble. De plus, il peut faire des choses intéressantes comme AppendLine.
la source
Dans .NET, StringBuilder est toujours plus rapide que l'ajout de chaînes. Je suis presque sûr qu'en Java, ils créent simplement un StringBuffer sous le capot lorsque vous ajoutez des chaînes, donc il n'y a pas vraiment de différence. Je ne sais pas pourquoi ils ne l'ont pas encore fait dans .NET.
la source
Considérez « La triste tragédie du théâtre de micro-optimisation ».
la source
L'utilisation de chaînes pour la concaténation peut entraîner une complexité d'exécution de l'ordre de
O(n^2)
.Si vous utilisez un
StringBuilder
, il y a beaucoup moins de copie de mémoire à faire. Avec le,StringBuilder(int capacity)
vous pouvez augmenter les performances si vous pouvez estimer la taille de la finaleString
. Même si vous n'êtes pas précis, vous n'aurez probablement qu'à augmenter la capacité deStringBuilder
quelques fois, ce qui peut également améliorer les performances.la source
J'ai vu des gains de performances significatifs en utilisant l'
EnsureCapacity(int capacity)
appel de méthode sur une instance deStringBuilder
avant de l'utiliser pour tout stockage de chaîne. J'appelle généralement cela sur la ligne de code après instanciation. Cela a le même effet que si vous instanciezStringBuilder
comme ceci:Cet appel alloue la mémoire nécessaire à l'avance, ce qui entraîne moins d'allocations de mémoire lors de plusieurs
Append()
opérations. Vous devez faire une estimation éclairée de la quantité de mémoire dont vous aurez besoin, mais pour la plupart des applications, cela ne devrait pas être trop difficile. Je me trompe généralement du côté d'un peu trop de mémoire (nous parlons environ 1k).la source
EnsureCapacity
juste après l'StringBuilder
instanciation. Instancier simplementStringBuilder
comme ceci:var sb = new StringBuilder(int capacity)
.Suite aux réponses précédentes, la première chose que je fais toujours quand je pense à des problèmes comme celui-ci est de créer une petite application de test. Dans cette application, effectuez un test de synchronisation pour les deux scénarios et voyez par vous-même ce qui est plus rapide.
À mon humble avis, l'ajout de plus de 500 entrées de chaîne devrait certainement utiliser StringBuilder.
la source
String et StringBuilder sont en fait tous deux immuables, le StringBuilder a intégré des tampons qui permettent de gérer sa taille plus efficacement. Lorsque le StringBuilder doit être redimensionné, c'est lorsqu'il est réalloué sur le tas. Par défaut, il a une taille de 16 caractères, vous pouvez le définir dans le constructeur.
par exemple.
StringBuilder sb = nouveau StringBuilder (50);
la source
La concaténation de chaînes vous coûtera plus cher. En Java, vous pouvez utiliser StringBuffer ou StringBuilder en fonction de vos besoins. Si vous voulez une implémentation synchronisée et thread-safe, optez pour StringBuffer. Ce sera plus rapide que la concaténation de chaînes.
Si vous n'avez pas besoin d'une implémentation synchronisée ou Thread safe, optez pour StringBuilder. Ce sera plus rapide que la concaténation de chaînes et aussi plus rapide que StringBuffer car il n'y a pas de surcharge de synchronisation.
la source
StringBuilder est probablement préférable. La raison en est qu'il alloue plus d'espace que nécessaire actuellement (vous définissez le nombre de caractères) pour laisser de la place pour les ajouts futurs. Ensuite, ces ajouts futurs qui tiennent dans le tampon actuel ne nécessitent aucune allocation de mémoire ou récupération de place, ce qui peut être coûteux. En général, j'utilise StringBuilder pour la concatentation de chaînes complexes ou la mise en forme multiple, puis convertis en une chaîne normale lorsque les données sont terminées, et je veux à nouveau un objet immuable.
la source
Si vous faites beaucoup de concaténation de chaînes, utilisez un StringBuilder. Lorsque vous concaténez avec une chaîne, vous créez une nouvelle chaîne à chaque fois, en utilisant plus de mémoire.
Alex
la source
En règle générale, si je dois définir la valeur de la chaîne plus d'une fois ou s'il y a des ajouts à la chaîne, il doit s'agir d'un générateur de chaîne. J'ai vu des applications que j'ai écrites dans le passé avant d'en apprendre davantage sur les constructeurs de chaînes qui ont eu une énorme empreinte mémoire qui semble simplement continuer de croître. La modification de ces programmes pour utiliser le générateur de chaînes a considérablement réduit l'utilisation de la mémoire. Maintenant, je le jure par le constructeur de cordes.
la source
Mon approche a toujours été d'utiliser StringBuilder lors de la concaténation de 4 chaînes ou plus OU lorsque je ne sais pas comment les concaténations doivent avoir lieu.
Bon article sur les performances ici
la source
StringBuilder
est nettement plus efficace mais vous ne verrez pas ces performances à moins que vous ne fassiez une grande quantité de modification de chaîne.Vous trouverez ci-dessous un morceau de code rapide pour donner un exemple des performances. Comme vous pouvez le voir, vous ne commencez vraiment à voir une augmentation importante des performances que lorsque vous entrez dans de grandes itérations.
Comme vous pouvez le voir, les 200 000 itérations ont pris 22 secondes tandis que le million d'itérations utilisant le a
StringBuilder
été presque instantané.Résultat du code ci-dessus:
la source
StringBuilder fonctionnera mieux, du point de vue de la mémoire. Quant au traitement, la différence de temps d'exécution peut être négligeable.
la source