Je suis un peu confus quant à l’utilisation de StringBuilder
class, d’abord:
Une opération de concaténation d'objet
string
crée toujours un nouvel objet à partir destring
existant et des nouvelles données. Un objetStringBuilder
maintient un tampon pour permettre la concaténation de nouvelles données. Les nouvelles données sont ajoutées à la fin de la mémoire tampon si de la place est disponible; sinon, un nouveau tampon plus grand est alloué, les données du tampon d'origine sont copiées dans le nouveau tampon, puis les nouvelles données sont ajoutées au nouveau tampon.
Mais à quoi sert-il de créer StringBuilder
instance pour éviter de créer une nouvelle instance de String
? Cela ressemble à un échange "un pour un".
static void Main(string[] args)
{
String foo = "123";
using (StringBuilder sb = new StringBuilder(foo)) // also sb isn't disposable, so there will be error
{
sb.Append("456");
foo = sb.ToString();
}
Console.WriteLine(foo);
Console.ReadKey();
}
Pourquoi je ne devrais pas simplement utiliser
+=
Edit: Ok, je sais maintenant comment réutiliser une instance de StringBuilder
(je ne sais toujours pas si cela est correct avec les normes de code), mais cela ne vaut pas la peine d'être utilisé avec un seul string
, n'est-ce pas?
Modifier immuable des structures telles que string
s doit être fait en copiant la structure et en consommant plus de mémoire et ralentir le temps d'exécution de l'application (augmentant également le temps GC
, etc ...).
StringBuilder
vient résoudre ce problème en utilisant le même objet mutable pour les manipulations.
Cependant:
lors de la concaténation de string
au moment de la compilation, comme suit:
string myString = "123";
myString += "234";
myString += "345";
il va en fait compiler quelque chose comme ça:
string myString = string.Concat("123", "234", "345");
cette fonction est plus rapide que de travailler avec StringBuilder
pour le nombre de string
s entrant dans la fonction est connue.
donc, pour les concaténations string
connues au moment de la compilation, vous devriez préférer string.Concat()
.
comme pour un nombre inconnu de string
comme dans le cas suivant:
string myString = "123";
if (Console.ReadLine() == "a")
{
myString += "234";
}
myString += "345";
Maintenant, le compilateur ne peut pas utiliser la fonction string.Concat()
, cependant, StringBuilder
semble être plus efficace en termes de consommation de temps et de mémoire uniquement lorsque la concaténation est effectuée à 6-7 ou plus strings
.
Mauvais usage pratique:
StringBuilder myString = new StringBuilder("123");
myString.Append("234");
myString.Append("345");
Utilisation pratique fine (notez que if
est utilisé):
StringBuilder myString = new StringBuilder("123");
if (Console.ReadLine() == "a")
{
myString.Append("234");
}
myString.Append("345");
Utilisation recommandée (notez que la boucle while
est utilisée):
StringBuilder myString = new StringBuilder("123");
while (Console.ReadLine() == "a")
{
myString.Append("234"); //Average loop times 4~ or more
}
myString.Append("345");
Un string
est un classe immuable. Vous ne pouvez pas le modifier, créez seulement un nouveau strings
.
Ainsi, lorsque vous écrivez result += a;
, Vous avez trois strings
en mémoire à cet endroit: a
, l'ancienne valeur de result
et la nouvelle valeur. Bien sûr, c'est parfait si vous ne concaténez qu'un nombre limité de strings
. Si vous faites cela dans une boucle for
itérant une grande collection, cela peut devenir un problème.
La classe StringBuilder
offre de meilleures performances dans ces cas. Au lieu de créer un nouveau strings
pour stocker le résultat de la concaténation, il utilise le même objet. Donc, si vous utilisez stringBuilder.Append(a);
, vous n’aurez jamais l’équivalent de "l'ancienne valeur de result
".
Cette efficacité de la mémoire a un prix bien sûr. Lorsque vous concaténez seulement un petit nombre de strings
un StringBuilder
est souvent moins efficace en termes de rapidité, car il y avait plus de temps système par rapport à la classe immuable string
.
Une chose à garder à l'esprit est que lorsque vous avez besoin des chaînes intermédiaires, alors StringBuilder
peut devenir moins efficace, car appeler .ToString()
crée une nouvelle copie de string
.
La raison en est que strings
sont immuables. Lors de la concaténation d'un string
, vous créez un nouveau string
. Ainsi, lorsque vous devez concaténer plusieurs strings
, vous créez beaucoup de objects
. Cela ne coûte pas cher en termes de mémoire, car chaque string
est utilisé une fois. Mais cela donne du travail supplémentaire pour le GC
.
StringBuilder
utilise cependant le même object
à chaque fois, mais au détriment de la facilité d'utilisation.