web-dev-qa-db-fra.com

Quand utiliser StringBuilder?

Je comprends les avantages de StringBuilder.

Mais si je veux concaténer 2 chaînes, je suppose qu'il est préférable (plus rapide) de le faire sans StringBuilder. Est-ce correct?

À quel moment (nombre de chaînes) devient-il préférable d'utiliser StringBuilder?

64
Shiraz Bhaiji

Je vous suggère chaleureusement de lire The Sad Tragedy of Micro-Optimization Theatre , par Jeff Atwood.

Il traite la concaténation simple contre StringBuilder contre d'autres méthodes.

Maintenant, si vous voulez voir des chiffres et des graphiques, suivez le lien;)

69
Alex Bagnolini

Mais si je veux concaténer 2 chaînes, je suppose qu'il est préférable (plus rapide) de le faire sans StringBuilder. Est-ce correct?

C'est en effet correct, vous pouvez trouver pourquoi exactement expliqué très bien sur:

http://www.yoda.arachsys.com/csharp/stringbuilder.html

En résumé: si vous pouvez concaténer des cordes en une seule fois comme

var result = a + " " + b  + " " + c + ..

vous êtes mieux sans StringBuilder car seule la copie est effectuée (la longueur de la chaîne résultante est calculée au préalable.);

Pour une structure comme

var result = a;
result  += " ";
result  += b;
result  += " ";
result  += c;
..

de nouveaux objets sont créés à chaque fois, vous devez donc considérer StringBuilder.

À la fin, l'article résume ces règles générales:

Règles de base

Alors, quand devez-vous utiliser StringBuilder et quand devez-vous utiliser les opérateurs de concaténation de chaînes?

  • Utilisez certainement StringBuilder lorsque vous concaténez dans une boucle non triviale - surtout si vous ne savez pas avec certitude (au moment de la compilation) combien d'itérations vous ferez à travers la boucle. Par exemple, lire un fichier un caractère à la fois, construire une chaîne au fur et à mesure de l'utilisation de l'opérateur + = est potentiellement un suicide de performance.

  • Utilisez certainement l'opérateur de concaténation lorsque vous pouvez (de manière lisible) spécifier tout ce qui doit être concaténé dans une seule instruction. (Si vous avez un tableau d'éléments à concaténer, pensez à appeler explicitement String.Concat - ou String.Join si vous avez besoin d'un délimiteur.)

  • N'ayez pas peur de diviser les littéraux en plusieurs bits concaténés - le résultat sera le même. Vous pouvez améliorer la lisibilité en divisant un long littéral en plusieurs lignes, par exemple, sans nuire aux performances.

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

  • Si vous n'avez que quelques enchaînements à faire et que vous voulez vraiment les faire dans des instructions séparées, peu importe la direction que vous prenez. La méthode la plus efficace dépendra du nombre de concaténations, de la taille des chaînes impliquées et de l'ordre dans lequel elles sont concaténées.

39
Peter

System.String est un objet immuable - cela signifie que chaque fois que vous modifiez son contenu, il alloue une nouvelle chaîne et cela prend du temps (et de la mémoire?). À l'aide de StringBuilder, vous modifiez le contenu réel de l'objet sans en affecter un nouveau.

Utilisez donc StringBuilder lorsque vous devez effectuer de nombreuses modifications sur la chaîne.

11
Victor Hurdugaci

Pas vraiment ... vous devriez utiliser StringBuilder si vous concaténez des chaînes large ou si vous avez plusieurs concaténations, comme dans une boucle.

8
Bobby

Mais si je veux concaténer 2 chaînes, je suppose qu'il est préférable et plus rapide de le faire sans StringBuilder. Est-ce correct?

Oui. Mais plus important encore, il est beaucoup plus lisible d'utiliser un Vanilla String dans de telles situations. En revanche, son utilisation en boucle est logique et peut également être aussi lisible que la concaténation.

Je me méfierais des règles empiriques qui citent des nombres spécifiques de concaténation comme seuil. Son utilisation dans les boucles (et les boucles uniquement) est probablement tout aussi utile, plus facile à mémoriser et plus logique.

4
Konrad Rudolph

Il n'y a pas de réponse définitive, seulement des règles empiriques. Mes propres règles personnelles vont comme ceci:

  • En cas de concaténation dans une boucle, utilisez toujours un StringBuilder.
  • Si les chaînes sont grandes, utilisez toujours un StringBuilder.
  • Si le code de concaténation est bien rangé et lisible à l'écran, il est probablement correct.
    Si ce n'est pas le cas, utilisez un StringBuilder.
4
LukeH

Paraphraser

Alors tu compteras jusqu'à trois, ni plus, ni moins. Trois sera le nombre que tu compteras, et le nombre du comptage sera de trois. Tu ne compteras pas quatre, tu ne compteras pas deux, sauf que tu passeras ensuite à trois. Une fois que le numéro trois, étant le troisième numéro, est atteint, alors lobbest thou thy Holy Hand Grenade of Antiioch

J'utilise généralement le générateur de chaînes pour tout bloc de code qui entraînerait la concaténation de trois chaînes ou plus.

4
Russell Steen
  • Si vous concaténez des chaînes dans une boucle, vous devriez envisager d'utiliser StringBuilder au lieu de String normal
  • Dans le cas d'une concaténation unique, vous ne verrez peut-être pas du tout la différence de temps d'exécution

Voici une application de test simple pour prouver le point:

class Program
{
    static void Main(string[] args)
    {
        const int testLength = 30000;
        var StartTime = DateTime.Now;

        //TEST 1 - String
        StartTime = DateTime.Now;
        String tString = "test string";
        for (int i = 0; i < testLength; i++)
        {
            tString += i.ToString();
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 2000 ms

        //TEST 2 - StringBuilder
        StartTime = DateTime.Now;
        StringBuilder tSB = new StringBuilder("test string");
        for (int i = 0; i < testLength; i++)
        {
            tSB.Append(i.ToString());
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 4 ms

        Console.ReadLine();
    }
}

Résultats:

  • 30'000 itérations

    • Chaîne - 2000 ms
    • StringBuilder - 4 ms
  • 1000 itérations

    • Chaîne - 2 ms
    • StringBuilder - 1 ms
  • 500 itérations

    • Chaîne - 0 ms
    • StringBuilder - 0 ms
4
adrian.krzysztofek

Tant que vous pouvez taper physiquement le nombre de concaténations (a + b + c ...), cela ne devrait pas faire une grande différence. N au carré (à N = 10) est un ralentissement de 100X, ce qui ne devrait pas être trop mauvais.

Le gros problème est lorsque vous concatène des centaines de chaînes. À N = 100, vous obtenez un ralentissement de 10000X fois. Ce qui est plutôt mauvais.

3
wisty

Je ne pense pas qu'il y ait une frontière fine entre quand utiliser et quand ne pas le faire. À moins bien sûr que quelqu'un ait effectué des tests approfondis pour en sortir avec les conditions d'or.

Pour moi, je n'utiliserai pas StringBuilder si je concatène juste 2 énormes chaînes. S'il y a une boucle avec un nombre indéterminé, je le suis probablement, même si la boucle peut être de petits nombres.

2
o.k.w

Une seule concaténation ne vaut pas l'utilisation d'un StringBuilder. J'ai généralement utilisé 5 concaténations en règle générale.

1
Matt Wrock

La classe StringBuilder fournit au développeur un ensemble de méthodes qui permet la manipulation d'une chaîne de caractères modifiable, elle peut être utilisée lorsque vous souhaitez modifier une chaîne sans créer un nouvel objet, éliminant ainsi la surcharge ou problème de goulot d'étranglement de la concaténation de chaîne normale.

L'utilisation de la classe StringBuilder peut améliorer les performances lors de la concaténation de nombreuses chaînes dans une boucle.

Voici une liste de quelques opérations qui peuvent être effectuées pour manipuler une chaîne à l'aide de la classe StringBuilder dans .NET

Append: ajoute des informations à la fin du StringBuilder actuel.

AppendFormat: remplace un spécificateur de format passé dans une chaîne par du texte formaté.

Insérer: insère une chaîne ou un objet dans l'index spécifié du StringBuilder actuel.

Remove: supprime un nombre spécifié de caractères du StringBuilder actuel.

Replace: remplace un caractère spécifié à un index spécifié.

0
Mohammad Ali Rony