12
votes

StringBuilder utilise-t-il plus de mémoire que la concaténation de la chaîne?

Je connais l'avantage de performance évident d'utiliser le StringBuilder est en C #, mais quelle est la différence de mémoire?

Le StressBuilder utilise-t-il plus de mémoire? Et comme note latérale, quelle que soit l'essentiellement, le StringBuilder fait différemment qui le rend tellement plus rapide?


0 commentaires

3 Réponses :


5
votes

Je pense que vous devriez vraiment lire ceci: La tragédie triste du théâtre de micro-optimisation , votre réponse de StringBuilder V / S Concat, après le saut


0 commentaires

16
votes

StringBuilder n'est pas nécessairement plus rapide. Si je me souviens, si vous êtes concultiant moins d'une douzaine de chaînes, une concaté de cordes (eiether via string.concat ou STR1 + STR2) est effectivement plus rapide. La raison en est que l'allocation et l'initialisation de StringBuilder prend du temps.

La raison pour laquelle StringBuilder est plus rapide est qu'il crée un tampon interne qu'il ajoute des chaînes à. Si vous concatéez 20 chaînes, StringBuilder ajoute simplement l'une après l'autre à sa mémoire tampon et renvoie enfin le résultat lorsqu'il est demandé - via sa méthode Tostring (). (Je suppose qu'il y ait suffisamment d'espace tampon. Sinon StringBuilder s'inquiète de la réaffectation du tampon et a une heuristique pour l'aider à ne pas réaffecter trop de fois.) Si vous étiez des chaînes concatantes, chaque chaîne concessive allouerait une nouvelle chaîne de Longueur (str1.longueur + str2.length) et copiez la première et la deuxième chaîne en place. Cela se traduit par beaucoup de recyclage de chaînes. xxx

Cela nécessitera des allocations N-1 et des opérations de copie N-1. Cela peut être très coûteux pour les grandes N. Plus Notez que vous copiez le contenu de STR1 N-1 fois. Une fois pour obtenir le résultat de STR1 + STR2. Encore une fois pour obtenir le résultat de (str1 + str2) + str3. Avec StringBuilder, chaque chaîne est copiée dans la mémoire tampon interne une seule fois, en supposant que le tampon est suffisamment grand pour maintenir les chaînes individuelles.


2 commentaires

Je crois que les premières phrases de votre paragraphe de clôture sont incorrectes. Une seule ligne concaténant de nombreuses chaînes de cette manière sera, à moins que je ne me trompe, compilez à un seul appel string.concat , qui attribue exactement suffisamment d'espace pour la chaîne résultante une fois, sans avoir à effectuer plusieurs réaffectations comme vous le suggérez.


Le compilateur C # peut avoir cette optimisation. Je n'ai pas vérifié. Plus souvent que non, ces types de concats sont effectués à l'intérieur d'une boucle pour la boucle, ce qui ne peut être optimisé. Le compilateur C # optimise pour le cas où vous concultiez une série de chaînes constantes, ce qui entraîne le compilateur émettant une seule chaîne constante et en évitant complètement la concaté de temps d'exécution.



17
votes

Réponse courte: StringBuilder est approprié dans les cas où vous concatéez un nombre arbitraire de chaînes, que vous ne connaissez pas au moment de la compilation.

Si vous faire sais quelles chaînes vous combinez au moment de la compilation, stringbuilder est essentiellement inutile car vous n'avez pas besoin de capacités de redimensionnement dynamiques.

Exemple 1: Vous voulez combiner "chat", "chien" et "souris". C'est exactement 11 caractères. Vous pouvez simplement allouer un tableau char [] de longueur 11 et remplissez-le avec les caractères de ces chaînes. C'est essentiellement ce que string.concat fait.

Exemple 2: Vous souhaitez rejoindre un nombre non spécifié de chaînes fournies par l'utilisateur en une seule chaîne. Étant donné que la quantité de données à concaténer est inconnue à l'avance, l'utilisation d'un stringbuilder est approprié dans ce cas.


0 commentaires