Chaîne de contre StringBuilder
Je comprends la différence entre String
et StringBuilder
(StringBuilder
être mutable) mais est-il une grande différence de performance entre les deux?
Le programme que je suis en train de travailler sur a beaucoup de cas conduit chaîne ajoute (+de 500). Est l'aide de StringBuilder
un meilleur choix?
Vous devez vous connecter pour publier un commentaire.
Oui, la différence de performance est importante. Consultez l'article base de connaissances "Comment améliorer les performances de concaténation de chaîne dans Visual C#".
J'ai toujours essayé de code pour plus de clarté, d'abord, et ensuite optimiser les performances plus tard. C'est beaucoup plus facile que de le faire dans l'autre sens! Cependant, vu l'énorme différence de performances dans mes applications entre les deux, je pense maintenant un peu plus de soin.
Heureusement, il est relativement facile à exécuter l'analyse des performances de votre code pour voir où vous êtes passé du temps, et ensuite de le modifier pour utiliser
StringBuilder
en cas de besoin.De clarifier ce que Gillian a dit à propos de 4 cordes, si vous avez quelque chose comme ceci:
alors il serait plus rapide à l'aide de cordes et de l'opérateur plus. C'est parce que (comme Java, comme Eric souligne), il utilise en interne StringBuilder automatiquement (en Fait, il utilise une primitive StringBuilder utilise également)
Cependant, si ce que vous faites est de se rapprocher d':
Alors vous avez besoin pour utiliser explicitement un StringBuilder. .Net ne fait pas automatiquement de créer un StringBuilder ici, parce que ce serait inutile. À la fin de chaque ligne, "un" doit être un (immuable) de la chaîne, de sorte qu'il aurait à créer et disposer d'un StringBuilder sur chaque ligne. Pour la vitesse, vous devez utiliser le même StringBuilder jusqu'à ce que vous avez terminé la construction:
a
est une variable locale, et l'objet de référence n'a pas été attribué à une autre variable (qui peut être accessible pour un autre thread), un bon optimiseur pourrait déterminer que laa
n'est pas accessible à par tout autre code au cours de cette séquence de lignes; seulement le final valeur dea
questions. Il peut donc traiter ces trois lignes de code que si elles ont été écritesa = b + c + d;
.StringBuilder est préférable SI que vous faites de multiples boucles, ou de fourchettes dans votre code pass... cependant, au niveau des performances PURES, si vous pouvez vous en sortir avec une UNIQUE chaîne de déclaration, alors que c'est beaucoup plus performant.
Par exemple:
est plus performant que
Dans ce cas, Chaîneconstruit pouvait être considérée comme plus facile à gérer, mais n'est pas plus performant que l'unique chaîne de déclaration.
9 fois sur 10 si... utiliser le générateur de chaîne.
Sur une note de côté: string + var est également plus performant que la chaîne.Format d'approche (en général), qui utilise un StringBuilder en interne (dans le doute... vérifier réflecteur!)
Ce test montre que la pratique régulière de la concaténation est plus rapide lors de la combinaison de 3 ou moins de chaînes.
http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/
StringBuilder peuvent apporter une amélioration significative dans l'utilisation de la mémoire, surtout dans votre cas de l'ajout de 500 chaînes.
Considérons l'exemple suivant:
Ce qui se passe dans la mémoire? Les chaînes de caractères suivantes sont créées:
Par l'ajout de ces cinq nombres à la fin de la chaîne, nous avons créé 13 objets string! Et 12 d'entre eux ont été inutiles! Wow!
StringBuilder résout ce problème. Ce n'est pas un "mutable chaîne" comme on l'entend souvent (toutes les chaînes dans .NET sont immuables). Il fonctionne en gardant une mémoire tampon interne, un tableau de char. Appel Append() ou AppendLine() ajoute la chaîne de l'espace vide à la fin de la char tableau; si le tableau est trop petit, il crée un nouveau, plus grand tableau, et des copies de la mémoire tampon de là. Ainsi dans l'exemple ci-dessus, StringBuilder pourraient n'avoir besoin que d'un seul tableau pour contenir tous les 5 ajouts à la chaîne-- en fonction de la taille de son buffer. Vous pouvez dire StringBuilder quelle taille de son buffer doit être dans le constructeur.
i.ToString()
. Donc, avec StringBuilder, vous avez encore à créer 6 + 1 chaînes de caractères; il réduit la création de 13 chaînes à la création de 7 cordes. Mais c'est toujours la mauvaise façon de voir les choses; la création des six chaînes de nombre n'est pas pertinent. Bottom line: il vous suffit de ne pas avoir mentionné la six cordes, créé pari.ToString()
; ils ne font pas partie de l'efficacité de comparaison.Un exemple simple de démontrer la différence de vitesse lors de l'utilisation de
String
concaténation vsStringBuilder
:Résultat:
Résultat:
Comme un résultat, la première itération a pris 15423 ms, tandis que la deuxième itération à l'aide de
StringBuilder
a pris 10 ms.Il me semble que l'utilisation de
StringBuilder
est plus rapide, beaucoup plus rapide.Oui,
StringBuilder
offre de meilleures performances lors de l'exécution d'une utilisation répétée sur une chaîne. C'est parce que toutes les modifications sont apportées à une instance unique de sorte qu'il peut gagner beaucoup de temps au lieu de créer une nouvelle instance commeString
.Chaîne Vs Stringbuilder
String
System
espace de nomsStringBuilder
(mutable string)System.Text
espace de nomsStringBuilder réduit le nombre de répartitions et attributions, à un coût supplémentaire de mémoire utilisée. Utilisé correctement, il peut éliminer complètement la nécessité pour le compilateur d'allouer de plus en plus grandes chaînes, jusqu'à ce que le résultat est obtenu.
vs
Chaîne De Vs Le Générateur De Chaîne:
Première chose que vous devez savoir que Dans l'assemblage de ces deux classes de vies?
Donc,
chaîne est présent dans
System
espace de noms.et
StringBuilder est présent dans
System.Text
espace de noms.Pour chaîne déclaration:
Vous devez inclure le
System
espace de noms.quelque chose comme cela.
Using System;
et
Pour StringBuilder déclaration:
Vous devez inclure le
System.text
espace de noms.quelque chose comme cela.
Using System.text;
Maintenant, Venez à la, la Question réelle.
Quelle est la differene entre chaîne & StringBuilder?
La principale différence entre ces deux, c'est que:
chaîne est immuable.
et
StringBuilder est mutable.
Alors Maintenant, permet de discuter de la différence entre immuable et mutable
Mutable: : signifie Changable.
Immuable: : signifie Pas Changable.
Par exemple:
Donc, dans ce cas, nous allons à l'évolution même de l'objet 5 fois.
Donc, la question Évidente est que ! Qu'est-ce que effectivement se produire sous le capot, lors du changement de la même chaîne de 5 fois.
C'est Ce qui Arrive lorsque nous changeons la même chaîne de 5 fois.
laisser regarder à la figure.
Explication:
Lorsque nous avons d'abord initialiser cette variable "nom" à "Rehan" i-e
string name = "Rehan"
cette variable créé sur la pile "nom" et soulignant que "Rehan" de la valeur.
après cette ligne est exécutée: "nom = nom + "Shah". la variable de référence n'est plus de pointage de l'objet "Rehan" aujourd'hui, il en pointant vers "Shah" et ainsi de suite.
Donc
string
est immuable, ce qui signifie que lorsque nous créons l'objet dans la mémoire, nous ne pouvons pas les changer.Ainsi, lorsque nous concatinating la
name
variable de l'objet précédent, il reste dans la mémoire et un autre nouvel objet string est créé...Donc, à partir de la figure ci-dessus, nous avons cinq objets les quatre objets sont jetés, ils ne sont pas utilisés. Ils stil restent en mémoire et ils occuy la quantité de mémoire.
"Garbage Collector" est responsable de la propreté que les ressources de la mémoire.
Ainsi dans le cas de la chaîne à tout moment lorsque l'on manipule la chaîne maintes et maintes fois nous avons un certain nombre d'objets Créés sna y rester au dans la mémoire.
C'est donc l'histoire d'une Variable de chaîne.
Maintenant, regardons vers l'Objet StringBuilder.
Par Exemple:
Donc, dans ce cas, nous allons à l'évolution même de l'objet 5 fois.
Donc, la question Évidente est que ! Qu'est-ce que effectivement se produire sous le capot, lors du changement de la même StringBuilder 5 fois.
C'est Ce qui Arrive lorsque nous changeons la même StringBuilder 5 fois.
laisser regarder à la figure.
Explication:
Dans le cas de l'objet StringBuilder. vous ne seriez pas obtenir le nouvel objet. Le même objet aura des changements dans la mémoire de sorte que même si vous modifiez l'objet et dire 10 000 fois, nous allons encore avoir un seul objet stringBuilder.
Vous n'avez pas beaucoup de déchets à des objets ou des non_referenced stringBuilder objets raison pourquoi il peut être le changement. Il est mutable sens-il changer avec le temps?
Différences:
dans le Système.Texte de l'espace de noms.
Source: MSDN
StringBuilder
est mieux pour la construction d'une chaîne de nombreux non-valeurs constantes.Si vous êtes en train de construire une chaîne de caractères à partir d'un lot de valeurs constantes, telles que les lignes multiples de valeurs dans un format HTML ou XML document ou d'autres morceaux de texte, vous pouvez vous en sortir avec juste l'ajout à la même chaîne, parce que presque tous les compilateurs ne "constantes", 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 de non-valeurs des constantes ajoutés les uns aux autres, l' .NET compilateur permettra de réduire votre code à quelque chose de semblable à ce queStringBuilder
n'.Mais quand votre ajout ne peut être réduite à quelque chose de plus simple par le compilateur, vous aurez besoin d'un
StringBuilder
. Comme fizch points, qui est plus susceptible de se produire à l'intérieur d'une boucle.Je crois StringBuilder est plus rapide si vous avez plus de 4 chaînes, vous devez ajouter ensemble. De Plus il peut faire des choses très intéressantes comme AppendLine.
Dans .NET, StringBuilder est encore plus rapide que d'ajouter des chaînes de caractères. Je suis assez sûr qu'en Java, ils suffit de créer un StringBuffer sous le capot lorsque vous ajoutez des chaînes de caractères, donc il n'est pas vraiment une différence. Je ne sais pas pourquoi ils n'ont pas fait cette dans le .NET encore.
Prendre en considération"La Triste Tragédie de la Micro-Optimisation de Théâtre'.
À l'aide de cordes pour la concaténation peut conduire à une exécution de la complexité, de l'ordre de
O(n^2)
.Si vous utilisez un
StringBuilder
, il y a beaucoup moins de la copie de la mémoire qui doit être fait. Avec leStringBuilder(int capacity)
vous pouvez augmenter les performances si vous pouvez estimer la taille de la finaleString
va être. Même si vous n'êtes pas précis, vous aurez probablement seulement augmenter la capacité deStringBuilder
une couple de fois, ce qui peut aider à la performance aussi.J'ai vu des gains de performance significatifs de l'utilisation de l'
EnsureCapacity(int capacity)
appel de méthode sur une instance deStringBuilder
avant de l'utiliser pour n'importe quelle chaîne de stockage. J'ai l'habitude de les appeler que sur la ligne de code après l'instanciation. Il a le même effet que si vous instanciez leStringBuilder
comme ceci:Cet appel alloue la mémoire nécessaire à l'avance, ce qui provoque moins d'allocations de mémoire pendant plusieurs
Append()
opérations. Vous devez faire une supposition éclairée sur la quantité de mémoire dont vous aurez besoin, mais pour la plupart des applications, cela ne devrait pas être trop difficile. J'ai l'habitude de se tromper sur le côté de un peu trop de mémoire (on parle ici de 1k ou presque).EnsureCapacity
juste après laStringBuilder
de l'instanciation. Instanciez leStringBuilder
comme ceci:var sb = new StringBuilder(int capacity)
.Suite à la réponse à la question précédente, la première chose que je fais toujours quand on pense à des questions de ce genre est de créer une petite application de test. À l'intérieur de cette application, effectuer quelques test de chronométrage pour les deux scénarios et de voir par vous-même ce qui est plus rapide.
À mon humble avis, en ajoutant plus de 500 entrées de chaîne doit certainement utiliser StringBuilder.
Chaîne et StringBuilder sont en fait les deux immuable, le StringBuilder a construit dans les tampons qui permettent de sa taille à être gérés plus efficacement. Lorsque le StringBuilder besoins pour redimensionner, c'est quand il est ré-alloué sur le tas. Par défaut, elle est de taille moyenne à 16 caractères, vous pouvez le faire dans le constructeur.
par exemple.
StringBuilder sb = new StringBuilder(50);
De concaténation de chaîne vous coûtera plus.
En Java, Vous pouvez utiliser StringBuffer ou StringBuilder en fonction de votre besoin.
Si vous voulez un synchronisé, et thread-safe mise en œuvre, rendez-vous pour StringBuffer. Ce sera plus rapide que la concaténation de Chaîne.
Si vous n'avez pas besoin synchronisé ou Thread-safe mise en œuvre, rendez-vous pour StringBuilder.
Ce sera plus rapide que la concaténation de Chaîne et également plus rapide que StringBuffer que leur a pas de synchorization frais généraux.
StringBuilder est probablement préférable. La raison en est qu'il n'alloue plus d'espace que nécessaire (vous pouvez définir le nombre de caractères) pour laisser de la place pour les futures ajoute. Alors que ces futurs ajoute que l'ajustement dans le tampon courant ne nécessitent pas d'allocation de mémoire ou de collecte des ordures, qui peut être coûteux. En général, je utiliser StringBuilder pour les complexes de la chaîne de concaténation ou plusieurs formatage, puis de les convertir à la normale de la Chaîne lorsque les données sont complètes, et je veux un objet immuable de nouveau.
Si vous faites beaucoup de concaténation de chaîne, utilisez un StringBuilder. Lorsque vous concaténer une Chaîne de caractères, vous créez une nouvelle Chaîne à chaque fois, à l'aide de plus de mémoire.
Alex
Comme une règle générale, si je dois mettre la valeur de la chaîne, plus d'une fois, ou si il y a de tout ajoute à la chaîne, puis il besoin d'être un générateur de chaîne. J'ai vu les demandes que j'ai écrit dans le passé avant d'en apprendre sur la chaîne de constructeurs qui ont eu une immense mémoire impression de pied qui semble juste pour continuer de croître et de grandir. La modification de ces programmes à utiliser le générateur de chaîne couper l'utilisation de la mémoire de manière significative. Maintenant je ne jure que par le générateur de chaîne.
Mon approche a toujours été d'utiliser StringBuilder lors de la concaténation de 4 ou plus de chaînes
OU
Quand je ne sais pas comment peut concaténations sont à prendre place.
Bon liées à la performance de l'article sur le sujet ici
StringBuilder
est beaucoup plus efficace, mais vous ne verrez que les performances sauf si vous faites une grande quantité de chaîne de modification.Ci-dessous est un bref morceau de code pour donner un exemple de la performance. Comme vous pouvez le voir vous avez vraiment commencer à voir une importante augmentation des performances lorsque vous arrivez à la grande itérations.
Comme vous pouvez le voir les 200 000 itérations a pris 22 secondes, tandis que les 1 millions d'itérations à l'aide de la
StringBuilder
a été presque instantanée.Résultat le code ci-dessus:
StringBuilder un meilleur rendement, à partir d'une mémoire de point de vue. Comme pour le traitement, la différence de temps d'exécution peut être négligeable.