Sí, la diferencia de rendimiento es significativa. Consulte el artículo de KB " Cómo mejorar el rendimiento de la concatenación de cadenas en Visual C # ".
Siempre he tratado de codificar por claridad primero, y luego optimizar el rendimiento más tarde. ¡Eso es mucho más fácil que hacerlo al revés! Sin embargo, habiendo visto la enorme diferencia de rendimiento en mis aplicaciones entre los dos, ahora lo pienso un poco más cuidadosamente.
Afortunadamente, es relativamente sencillo ejecutar un análisis de rendimiento en su código para ver dónde pasa el tiempo y luego modificarlo para usarlo StringBuilder
donde sea necesario.
Para aclarar lo que dijo Gillian sobre 4 cuerdas, si tiene algo como esto:
entonces sería más rápido usando cadenas y el operador más. Esto se debe a que (como Java, como señala Eric), usa internamente StringBuilder automáticamente (en realidad, usa una primitiva que StringBuilder también usa)
Sin embargo, si lo que está haciendo está más cerca de:
Luego debe usar explícitamente un StringBuilder. .Net no crea automáticamente un StringBuilder aquí, porque sería inútil. Al final de cada línea, "a" tiene que ser una cadena (inmutable), por lo que debería crear y disponer un StringBuilder en cada línea. Para la velocidad, necesitaría usar el mismo StringBuilder hasta que termine de construir:
fuente
a
trata de una variable local y el objeto al que hace referencia no se ha asignado a otra variable (que podría ser accesible a otro subproceso), un buen optimizador podría determinar que ningún otro códigoa
tiene acceso durante esta secuencia de líneas; solo el valor final de los asuntos. Por lo tanto, podría tratar esas tres líneas de código como si estuvieran escritas .a
a = b + c + d;
StringBuilder es preferible SI está haciendo múltiples bucles o bifurcaciones en su pase de código ... sin embargo, para un rendimiento PURO, si puede salirse con una declaración de cadena SINGLE , entonces eso es mucho más eficiente.
Por ejemplo:
es más eficiente que
En este caso, StringBuild podría considerarse más fácil de mantener, pero no es más eficaz que la declaración de cadena única.
9 de cada 10 veces ... sin embargo, use el generador de cadenas.
En una nota al margen: string + var también es más eficiente que el string.
fuente
Un ejemplo simple para demostrar la diferencia de velocidad cuando se usa la
String
concatenación vsStringBuilder
:Resultado:
Resultado:
Como resultado, la primera iteración tomó 15423 ms, mientras que la segunda iteración usando
StringBuilder
tomó 10 ms.Me parece que el uso
StringBuilder
es más rápido, mucho más rápido.fuente
Este punto de referencia muestra que la concatenación regular es más rápida cuando se combinan 3 o menos cadenas.
http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/
StringBuilder puede hacer una mejora muy significativa en el uso de la memoria, especialmente en el caso de agregar 500 cadenas juntas.
Considere el siguiente ejemplo:
¿Qué pasa en la memoria? Se crean las siguientes cadenas:
¡Al agregar esos cinco números al final de la cadena, creamos 13 objetos de cadena! ¡Y 12 de ellos fueron inútiles! ¡Guauu!
StringBuilder soluciona este problema. No es una "cadena mutable" como solemos escuchar ( todas las cadenas en .NET son inmutables ). Funciona manteniendo un búfer interno, una matriz de caracteres. Llamar a Append () o AppendLine () agrega la cadena al espacio vacío al final de la matriz de caracteres; si la matriz es demasiado pequeña, crea una nueva matriz más grande y copia el búfer allí. Entonces, en el ejemplo anterior, StringBuilder solo podría necesitar una matriz para contener las 5 adiciones a la cadena, dependiendo del tamaño de su búfer. Puede decirle a StringBuilder qué tan grande debe ser su búfer en el constructor.
fuente
i.ToString()
. Entonces, con StringBuilder, todavía tiene que crear 6 + 1 cadenas; redujo la creación de 13 cuerdas a la creación de 7 cuerdas. Pero esa sigue siendo la forma incorrecta de verlo; La creación de las cadenas de seis números no es relevante. En pocas palabras: simplemente no deberías haber mencionado las seis cadenas creadas pori.ToString()
; no son parte de la comparación de eficiencia.Sí,
StringBuilder
ofrece un mejor rendimiento al realizar operaciones repetidas en una cadena. Esto se debe a que todos los cambios se realizan en una sola instancia, por lo que puede ahorrar mucho tiempo en lugar de crear una nueva instancia comoString
.String Vs Stringbuilder
String
System
espacio de nombresStringBuilder
(cadena mutable)System.Text
espacio de nombresfuente
String Vs String Builder:
Lo primero que debes saber es ¿En qué asamblea viven estas dos clases?
Entonces,
la cadena está presente en el
System
espacio de nombres.y
StringBuilder está presente en el
System.Text
espacio de nombres.Para la declaración de cadena :
Tienes que incluir el
System
espacio de nombres. algo como esto.Using System;
y
Para la declaración de StringBuilder :
Tienes que incluir el
System.text
espacio de nombres. algo como esto.Using System.text;
Ahora viene la pregunta real.
¿Cuál es la diferencia entre string y StringBuilder ?
La principal diferencia entre estos dos es que:
La cadena es inmutable.
y
StringBuilder es mutable.
Así que ahora discutamos la diferencia entre inmutable y mutable
Mutable: significa que se puede cambiar.
Inmutable: significa que no se puede cambiar.
Por ejemplo:
Entonces, en este caso, vamos a cambiar el mismo objeto 5 veces.
¡Entonces la pregunta obvia es esa! Lo que realmente sucede debajo del capó, cuando cambiamos la misma cadena 5 veces.
Esto es lo que sucede cuando cambiamos la misma cadena 5 veces.
Miremos la figura.
Explicacion:
Cuando inicializamos esta variable "nombre" a "Rehan", es decir
string name = "Rehan"
esta variable se crea en la pila "nombre" y señala ese valor "Rehan". después de ejecutar esta línea: "nombre = nombre +" Shah ". La variable de referencia ya no apunta a ese objeto" Rehan ", ahora apunta a" Shah "y así sucesivamente.Entonces,
string
es inmutable lo que significa que una vez que creamos el objeto en la memoria no podemos cambiarlos.Entonces, cuando concatenamos la
name
variable, el objeto anterior permanece allí en la memoria y se crea otro nuevo objeto de cadena ...Entonces, de la figura anterior, tenemos cinco objetos, los cuatro objetos se tiran y no se usan en absoluto. Todavía permanecen en la memoria y ocupan la cantidad de memoria. El "recolector de basura" es el responsable de que los recursos de la memoria estén tan limpios.
Entonces, en el caso de una cadena en cualquier momento cuando manipulamos la cadena una y otra vez, tenemos muchos objetos creados y permanecen allí en la memoria.
Entonces esta es la historia de la variable de cadena.
Ahora veamos hacia el objeto StringBuilder. Por ejemplo:
Entonces, en este caso, vamos a cambiar el mismo objeto 5 veces.
¡Entonces la pregunta obvia es esa! Lo que realmente sucede debajo del capó, cuando cambiamos el mismo StringBuilder 5 veces.
Esto es lo que sucede cuando cambiamos el mismo StringBuilder 5 veces.
Miremos la figura.
Explicación: en el caso del objeto StringBuilder. no obtendrías el nuevo objeto. El mismo objeto cambiará en la memoria, por lo que incluso si cambia el objeto y dice 10,000 veces, todavía tendremos un solo objeto stringBuilder.
No tiene muchos objetos basura u objetos stringBuilder no referenciados porque se puede cambiar. ¿Es mutable, lo que significa que cambia con el tiempo?
Diferencias:
fuente
StringBuilder reduce el número de asignaciones y asignaciones, a un costo de memoria adicional utilizada. Si se usa correctamente, puede eliminar por completo la necesidad de que el compilador asigne cadenas cada vez más grandes una y otra vez hasta que se encuentre el resultado.
vs.
fuente
Fuente: MSDN
fuente
StringBuilder
es mejor para construir una cadena a partir de muchos valores no constantes.Si está creando una cadena a partir de una gran cantidad de valores constantes, como varias líneas de valores en un documento HTML o XML u otros fragmentos de texto, puede salirse con solo agregar a la misma cadena, porque casi todos los compiladores lo hacen "plegado constante", un proceso para reducir el árbol de análisis cuando tienes un montón de manipulación constante (también se usa cuando escribes algo así
int minutesPerYear = 24 * 365 * 60
). Y para casos simples con valores no constantes agregados entre sí, el compilador .NET reducirá su código a algo similar a lo queStringBuilder
hace.Pero cuando el compilador no puede reducir su apéndice a algo más simple, querrá un
StringBuilder
. Como señala fizch, es más probable que suceda dentro de un bucle.fuente
Creo que StringBuilder es más rápido si tiene más de 4 cadenas que necesita unir. Además, puede hacer algunas cosas interesantes como AppendLine.
fuente
En .NET, StringBuilder es aún más rápido que agregar cadenas. Estoy bastante seguro de que en Java, solo crean un StringBuffer debajo del capó cuando agregas cadenas, por lo que no hay realmente una diferencia. No estoy seguro de por qué aún no han hecho esto en .NET.
fuente
Considere ' La triste tragedia del teatro de micro-optimización '.
fuente
El uso de cadenas para la concatenación puede conducir a una complejidad de tiempo de ejecución del orden de
O(n^2)
.Si usa a
StringBuilder
, hay mucho menos copia de memoria que debe hacerse. Con elStringBuilder(int capacity)
puede aumentar el rendimiento si puede estimar qué tan grandeString
será la final . Incluso si no es preciso, probablemente solo tendrá que aumentar la capacidadStringBuilder
un par de veces, lo que también puede ayudar al rendimiento.fuente
He visto ganancias significativas de rendimiento al usar la
EnsureCapacity(int capacity)
llamada al método en una instancia deStringBuilder
antes de usarla para cualquier almacenamiento de cadenas. Normalmente llamo a eso en la línea de código después de la creación de instancias. Tiene el mismo efecto que si crea una instanciaStringBuilder
como esta:Esta llamada asigna la memoria necesaria antes de tiempo, lo que provoca menos asignaciones de memoria durante varias
Append()
operaciones. Debe hacer una suposición educada sobre cuánta memoria necesitará, pero para la mayoría de las aplicaciones esto no debería ser demasiado difícil. Por lo general, me equivoco con demasiada memoria (estamos hablando de 1k o menos).fuente
EnsureCapacity
justo después de laStringBuilder
instanciación. Simplemente una instancia de laStringBuilder
siguiente manera:var sb = new StringBuilder(int capacity)
.Además de las respuestas anteriores, lo primero que siempre hago cuando pienso en temas como este es crear una pequeña aplicación de prueba. Dentro de esta aplicación, realice una prueba de tiempo para ambos escenarios y vea por usted mismo cuál es más rápido.
En mi humilde opinión, agregar más de 500 entradas de cadena definitivamente debería usar StringBuilder.
fuente
String y StringBuilder son en realidad ambos inmutables, StringBuilder ha incorporado buffers que permiten que su tamaño se administre de manera más eficiente. Cuando StringBuilder necesita cambiar el tamaño es cuando se reasigna en el montón. Por defecto tiene un tamaño de 16 caracteres, puede configurar esto en el constructor.
p.ej.
StringBuilder sb = new StringBuilder (50);
fuente
La concatenación de cadenas le costará más. En Java, puede usar StringBuffer o StringBuilder según sus necesidades. Si desea una implementación sincronizada y segura para subprocesos, vaya a StringBuffer. Esto será más rápido que la concatenación de cadenas.
Si no necesita una implementación sincronizada o segura para subprocesos, vaya a StringBuilder. Esto será más rápido que la concatenación de String y también más rápido que StringBuffer ya que no hay sobrecarga de sincronización.
fuente
StringBuilder es probablemente preferible. La razón es que asigna más espacio del que se necesita actualmente (usted establece el número de caracteres) para dejar espacio para futuros anexos. Entonces, esos anexos futuros que encajan en el búfer actual no requieren ninguna asignación de memoria o recolección de basura, lo que puede ser costoso. En general, uso StringBuilder para la concatenación de cadenas complejas o el formato múltiple, luego convierto a una cadena normal cuando los datos están completos, y quiero un objeto inmutable nuevamente.
fuente
Si está haciendo mucha concatenación de cadenas, use un StringBuilder. Cuando concatena con una cadena, crea una nueva cadena cada vez, utilizando más memoria.
Alex
fuente
Como regla general, si tengo que establecer el valor de la cadena más de una vez, o si hay algunos agregados a la cadena, entonces debe ser un generador de cadenas. He visto aplicaciones que he escrito en el pasado antes de aprender sobre los constructores de cadenas que han tenido una gran huella de memoria que parece seguir creciendo y creciendo. Cambiar estos programas para usar el generador de cadenas redujo significativamente el uso de memoria. Ahora lo juro por el constructor de cuerdas.
fuente
Mi enfoque siempre ha sido usar StringBuilder al concatenar 4 o más cadenas O cuando no sé cómo se llevarán a cabo las concatenaciones.
Buen artículo relacionado con el rendimiento aquí
fuente
StringBuilder
es significativamente más eficiente, pero no verá ese rendimiento a menos que esté haciendo una gran cantidad de modificación de cadena.A continuación se muestra un fragmento rápido de código para dar un ejemplo del rendimiento. Como puede ver, en realidad solo comienza a ver un aumento importante en el rendimiento cuando entra en iteraciones grandes.
Como puede ver, las 200,000 iteraciones tomaron 22 segundos, mientras que el millón de iteraciones que usó
StringBuilder
fue casi instantáneo.Resultado del código anterior:
fuente
StringBuilder funcionará mejor, desde el punto de vista de la memoria. En cuanto al procesamiento, la diferencia en el tiempo de ejecución puede ser insignificante.
fuente