2009-12-01 9 views
51

Entiendo los beneficios de StringBuilder.Cuándo usar StringBuilder?

Pero si quiero concatenar 2 cadenas, supongo que es mejor (más rápido) hacerlo sin StringBuilder. ¿Es esto correcto?

¿En qué momento (número de cadenas) es mejor utilizar StringBuilder?

+1

Creo que esto ha sido cubierto previamente. –

+2

Muchas veces –

+1

Probables duplicados: http://stackoverflow.com/questions/529999, http://stackoverflow.com/questions/550702, http://stackoverflow.com/questions/1612797, http: // stackoverflow. com/questions/21078, http://stackoverflow.com/questions/73883, –

Respuesta

57

Le sugiero encarecidamente que lea The Sad Tragedy of Micro-Optimization Theater, por Jeff Atwood.

Se trata de Concatenación simple frente a StringBuilder frente a otros métodos.

Ahora, si quieres ver algunos números y gráficos, siga el enlace;)

+0

+1 por _yes_! El tiempo que pasamos preocupándonos por esto es el tiempo que pasamos sin hacer algo que realmente podría importar. –

+5

Sin embargo, su lectura es incorrecta: no importa en muchos casos, cuando no se trata de bucles, en otros casos, sin embargo, puede importar MUCHO – Peter

+0

He eliminado la edición, porque era información incorrecta en una respuesta aceptada . – Peter

1

Una sola concatenación no vale la pena usar un generador de cuerdas. Normalmente he usado 5 concatenaciones como regla general.

8

No realmente ... debe usar StringBuilder si concatena cadenas grandes o tiene muchas concatenaciones, como en un bucle.

+1

Eso es incorrecto. Debería usar 'StringBuilder' solo si el ciclo o la concatenación es un problema de rendimiento para las especificaciones. –

+0

-1 para una generalización incorrecta. cadena s = "a" + "b" + "c" + "d"; utiliza una asignación de memoria para s. Mire la última (novena) sobrecarga para string.Concat. El código anterior básicamente se compila en string.Concat ("a", "b", "c", "d") en MSIL. –

+2

@Alex: ¿No es siempre el caso? ;) No, en serio, siempre he usado StringBuilder para la concatenación dentro de un bucle ... aunque, todos mis bucles tienen más de 1k iteraciones ... @Binary: Normalmente, eso debería compilarse para 'string s =" abcd " ', al menos eso es lo último que escuché ... sin embargo, con las variables sería, muy probablemente, Concat. – Bobby

4

Pero si quiero concaturar 2 cadenas, supongo que es mejor (más rápido) hacerlo sin StringBuilder. ¿Es esto correcto?

Sí. Pero lo más importante es que es mucho más legible para usar un vainilla strings en tales situaciones. Usarlo en un ciclo, por otro lado, tiene sentido y también puede ser tan legible como la concatenación.

Sería cauteloso con las reglas generales que citan números específicos de concatenación como umbral. Usarlo en bucles (y bucles solamente) es probablemente igual de útil, más fácil de recordar y tiene más sentido.

+0

"Sería cauteloso con las reglas generales que citan números específicos de concatenación como un umbral"

34

Pero si quiero contatenar 2 cuerdas, entonces supongo que es mejor (más rápido) para hacer sin StringBuilder. ¿Es esto correcto?

Eso es de hecho correcta, se puede encontrar por qué se explica precisamente muy bien en:

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

resumió: si se puede contatenar cuerdas de una sola vez como

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

se es mejor sin stringbuilder porque solo se hace una copia (la longitud de la cadena resultante se calcula de antemano);

Para structurs como

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

se crean nuevos objetos cada vez, por lo que no se debe considerar StringBuilder.

Al final del artículo se resume estas reglas generales:

reglas generales

lo tanto, cuando se debe utilizar StringBuilder, y cuándo se debe utilizar los operadores de concatenación de cadenas ?

  • Definitivamente el uso de StringBuilder cuando que estés concatenar en un bucle no trivial - especialmente si usted no sabe a ciencia cierta (en tiempo de compilación) el número de iteraciones que va a hacer a través de la lazo. Por ejemplo, leer un archivo de un carácter a la vez, construir una cadena sobre la marcha con el operador + = es potencialmente un suicidio de rendimiento.

  • Definitivamente el uso del operador de concatenación cuando se puede (legible) especificar todo lo que necesita para ser concatenan en un comunicado. (Si tiene una serie de cosas a concatenar, considere llamar String.Concat explícitamente -. o string.join si necesita un delimitador)

  • No tenga miedo de romper los literales hasta en varias bits concatenados: el resultado será el mismo. Puede ayudar a la legibilidad de rompiendo un literal largo en varias líneas, por ejemplo, con sin dañar el rendimiento.

  • Si necesita los resultados intermedios de la concatenación de algo aparte de la alimentación de la siguiente iteración de concatenación, StringBuilder no es va a ayudar. Por ejemplo, si crea un nombre completo a partir de un primer nombre y un apellido, y luego agrega un tercer elemento de información (el apodo ), el solo se beneficiará del uso de StringBuilder si no necesita la cadena (primer nombre + ) para otro propósito (como hacemos en el ejemplo que crea un objeto Person).

  • Si sólo tiene unas pocas concatenaciones que hacer, y que realmente quiere hacerlas en declaraciones separadas, no importa el camino que tomes. ¿Qué manera es más eficiente dependerá de el número de concatenaciones los tamaños de cuerda involucrados, y en qué orden que están concatenados. Si usted realmente cree que pieza de código a ser un cuello de botella de rendimiento , perfil o compararlo en ambos sentidos.

8

System.String es un objeto inmutable - que significa que siempre que modifique su contenido se asignará una nueva cadena y esto lleva su tiempo (y la memoria?). El uso de StringBuilder modifica el contenido real del objeto sin asignar uno nuevo.

Así que use StringBuilder cuando necesite hacer muchas modificaciones en la cadena.

4

No hay una respuesta definitiva, solo reglas generales. Mis propias reglas personales más o menos así:

  • Si concatenar en un bucle, utilice siempre un StringBuilder.
  • Si las cadenas son grandes, utilice siempre un StringBuilder.
  • Si el código de concatenación es ordenado y legible en la pantalla, entonces probablemente esté bien.
    Si no es así, utilice un StringBuilder.
+0

Sé que este es un tema antiguo, pero solo sé aprender y quería saber lo que consideras una "cadena grande". – MatthewD

2

No creo que haya una línea fina entre cuándo usar o cuándo no. A menos, por supuesto, que alguien realice algunas pruebas exhaustivas para salir con las condiciones de oro.

Para mí, no usaré StringBuilder solo concatenar 2 cadenas enormes. Si hay un ciclo con un recuento indeterminado, es probable que lo haga, incluso si el ciclo fuera pequeño.

+0

De hecho, sería completamente incorrecto que ues StringBuilder concatene 2 cadenas, pero eso no tiene nada que ver con perf. prueba - eso es simplemente usarlo para lo incorrecto. –

3

Siempre que pueda escribir físicamente el número de concatenaciones (a + b + c ...) no debería hacer una gran diferencia. N al cuadrado (en N = 10) es una ralentización de 100X, lo que no debería ser tan malo.

El gran problema es cuando concatenas cientos de cadenas. En N = 100, obtienes una desaceleración de 10000X veces. Lo cual es bastante malo.

4

Parafraseando

entonces te contar hasta tres, ni más ni menos. Tres será el número que contarás, y el número del conteo será tres. Cuatro no contarás, ni contarás dos, excepto que luego pasarás a tres. Una vez que el número tres, siendo el tercer número, se puede alcanzar, entonces lobbest á tu Santo granada de mano de Antioquía

Yo generalmente uso constructor de cadena para cualquier bloque de código que daría lugar a la concatenación de tres o más cadenas.

+0

Depende: la Concepción solo hace una copia: "Russell" + "" + Steen + ".", Solo hará una copia porque calcula la longitud de la cadena de antemano. Solo cuando tenga que dividir su concatenación, debería comenzar a pensar en un constructor – Peter

2
  • Si concatena cadenas en un bucle, se debe considerar el uso de StringBuilder en lugar de cadena normal
  • En caso de que sea única concatenación, es posible que no vea la diferencia en tiempo de ejecución en absoluto

Aquí es una aplicación sencilla prueba para probar el punto:

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(); 
    } 
} 

resultados:

  • 30.000 iteraciones

    • de cuerda - 2000 ms
    • StringBuilder - 4 ms
  • 1000 iteraciones

    • String - 2 ms
    • Stri ngBuilder - 1 ms
  • 500 iteraciones

    • de Cuerda - 0 ms
    • StringBuilder - 0 ms
Cuestiones relacionadas