2009-11-17 7 views
7

J'ai une boucle for et ce que je fais est ceci.C# + = (plus égal à) (Affectation par addition) fonctionne très lentement, quand la chaîne est trop longue?

forloop (loop 7000 times) 
{ 
x += 2000_char_long_string; 
} 

Le code dure très longtemps dans ce forloop, peut-être plus de 1 minute. Comment puis-je résoudre ce problème?

Merci.

+0

Dans votre cas, il serait utile de spécifier la capacité au cours de l'initialisation de StringBuilder pour que votre code soit plus rapide et évite le surcoût dû à la réallocation de la mémoire dans StringBuilder. S'il vous plaît vérifier ma réponse ci-dessous. –

+4

StringBuilder déplace la boîte de peinture! http://www.joelonsoftware.com/articles/fog0000000319.html –

Répondre

45

Utilisez un StringBuilder.

StringBuilder sb = new StringBuilder(); 
for(int i=0; i< 200; i++){ 
    sb.append(longString); 
} 
return sb.ToString(); 

Lorsque vous utilisez += sur les chaînes, vous continuer à créer de nouvelles chaînes, et de garder la localisation des blocs plus en plus grandes de la mémoire. C'est pourquoi l'opération est si lente.

+2

+1 Simple comme :) – GenericTypeTea

+0

Wow, vraiment rapide. :) Merci. – stckvrflw

+6

Une amélioration serait également de définir la capacité initiale. Si vous allouez des chaînes de caractères 7000 * 2000, définissez la capacité initiale sur 14000000 pour éviter la croissance répétée du tampon. –

1

objet chaîne C# est immuable, chaque fois que le contenu est modifié nouvel objet est créé et le nouveau contenu sont copiés. Utilisez StringBuilder à la place, il est fourni pour résoudre le problème que vous rencontrez

+0

Je n'oublierai pas cela, information assez utile pour moi. Merci. – stckvrflw

14

En utilisant un StringBuilder, en tant que @Kobi referenced vous pouvez toujours augmenter les performances en l'initialisant. Il semble que vous pouvez déterminer la taille finale du string à l'avance.

StringBuilder sb = new StringBuilder(7000*2000); 
for(int i=0; i< 7000; i++){ 
    sb.append(2000_char_long_string); 
} 
return sb.ToString(); 
+1

Notez que même si vous n'êtes pas sûr de la longueur exacte, faites une estimation. La surcharge ne rajoute aucun surcoût (mémoire mise à part) et même si vous ne maîtrisez pas, vous allouerez toujours moins qu'avant. – Blindy

2

Les manipulations de chaînes sont immuables. Il y aura une nouvelle chaîne créée à chaque fois que stmt x + = 2000_char_long_string; est exécuté. Par conséquent, comme suggéré par Kobi, vous devez utiliser une classe StringBuilder.

Toutefois, dans votre cas, vous devez spécifier la capacité dans le constructeur StringBuilder.

En effet, si non spécifié, la capacité par défaut de StringBuilder lors de la création est 16.

Une fois que cette capacité est épuisée, il va créer un nouvel emplacement de mémoire contiguë, copier tout le contenu du StringBuilder au nouvel emplacement et pointez l'instance vers le nouvel emplacement. Puisque vous connaissez déjà la taille approximative de la chaîne finale (peut-être 7000 * 2000), vous pouvez spécifier la capacité en conséquence. Pour plus de détails, veuillez consulter ma réponse au StringBuilder and capacity?.

Questions connexes