2009-11-17 13 views
7

Tengo un bucle for y lo que hago es esto.C# + = (más igual) (Asignación por adición) trabajando muy lento, cuando la cadena es demasiado larga?

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

Código dura mucho tiempo en este forloop, tal vez más de 1 minuto. ¿Como puedó resolver esté problema?

Gracias.

+0

En su caso, sería útil especificar la capacidad durante la inicialización de StringBuilder para que su código sea más rápido y evitar la sobrecarga debido a la reasignación de memoria en StringBuilder. Por favor revisa mi respuesta a continuación. –

+4

¡StringBuilder mueve la lata de pintura! http://www.joelonsoftware.com/articles/fog0000000319.html –

Respuesta

45

Utilice un StringBuilder.

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

Cuando se utiliza += en las cuerdas, a mantener la creación de nuevas cadenas, y mantener la localización de los bloques más grandes de memoria. Es por eso que la operación es muy lenta.

+2

+1 Simple como :) – GenericTypeTea

+0

Guau, muy rápido. :) Gracias. – stckvrflw

+6

Una mejora sería establecer también la capacidad inicial. Si está asignando cadenas de caracteres de 7000 * 2000, configure la capacidad inicial en 14000000 para evitar el crecimiento repetido del búfer. –

1

objeto C# cadena es inmutable, cada vez que el contenido se cambian nuevo objeto se crea y los nuevos contenidos se copian. Use StringBuilder en su lugar, se proporciona para abordar el problema que está enfrentando

+0

No me olvidaré de eso, información bastante útil para mí. Gracias. – stckvrflw

14

Al usar StringBuilder, como @Kobi referenced, aún puede aumentar el rendimiento al inicializarlo. Parece que puede determinar el tamaño final de string con anticipación.

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

Tenga en cuenta que incluso si no está seguro de cuál es la longitud exacta, haga una mejor estimación. La sobrecarga no agrega ningún gasto adicional (la memoria a un lado) e incluso si lo hace, aún asignará menos que antes. – Blindy

2

Las manipulaciones de cadena son inmutables. Se creará una nueva cadena cada vez que stmt x + = 2000_char_long_string; es ejecutado. Por lo tanto, como sugiere Kobi, debe usar una clase StringBuilder.

Sin embargo, en su caso, debe especificar la capacidad en el constructor StringBuilder.

Esto se debe a que, si no se especifica, la capacidad por defecto de StringBuilder durante la creación es 16.

Una vez agotada esta capacidad, se creará una nueva ubicación de memoria contigua, copiar todos los contenidos de la StringBuilder a la nueva ubicación y apunte la instancia a la nueva ubicación. Como ya conoce el tamaño aproximado de la cadena final (tal vez 7000 * 2000), puede especificar la capacidad en consecuencia.

Por favor, consulte mi respuesta a StringBuilder and capacity? para más detalles.