net how c# .net string memory stringbuilder

c# - how - stringbuilder net



Cómo usar StringBuilder sabiamente (3)

La modificación de estructuras immutable como string s se debe hacer copiando la estructura y, por lo tanto, consumiendo más memoria y ralentizando el tiempo de ejecución de la aplicación (aumentando también el tiempo de GC , etc.).

StringBuilder viene a resolver este problema usando el mismo objeto mutable para manipulaciones.

Sin embargo:

al concatenar una string en tiempo de compilación de la siguiente manera:

string myString = "123"; myString += "234"; myString += "345";

en realidad se compilará a algo así:

string myString = string.Concat("123", "234", "345");

esta función es más rápida que trabajar con StringBuilder porque se conoce el número de string entran en la función.

por lo tanto, para string concatenaciones de string conocidas en tiempo de compilación, debería preferir string.Concat() .

en cuanto a la cantidad desconocida de string como en el siguiente caso:

string myString = "123"; if (Console.ReadLine() == "a") { myString += "234"; } myString += "345";

Ahora el compilador no puede usar la función string.Concat() , sin embargo, StringBuilder parece ser más eficiente en tiempo y consumo de memoria solo cuando la concatenación se hace con 6-7 o más strings .

Uso de mala práctica:

StringBuilder myString = new StringBuilder("123"); myString.Append("234"); myString.Append("345");

Uso adecuado de la práctica (tenga en cuenta que if se usa):

StringBuilder myString = new StringBuilder("123"); if (Console.ReadLine() == "a") { myString.Append("234"); } myString.Append("345");

Uso de mejores prácticas (tenga en cuenta que while loop se usa):

StringBuilder myString = new StringBuilder("123"); while (Console.ReadLine() == "a") { myString.Append("234"); //Average loop times 4~ or more } myString.Append("345");

Estoy un poco confundido sobre el uso de la clase StringBuilder , primero:

Una operación de concatenación de objeto de string siempre crea un nuevo objeto a partir de la string existente y los datos nuevos. Un objeto StringBuilder mantiene un búfer para acomodar la concatenación de datos nuevos. Se añaden nuevos datos al final del búfer si hay espacio disponible; de lo contrario, se asigna un nuevo búfer más grande, los datos del búfer original se copian en el nuevo búfer, y luego se añaden los nuevos datos al nuevo búfer.

Pero, ¿de qué sirve crear una instancia de StringBuilder para evitar crear una nueva de String ? Suena como intercambiar "uno por uno".

static void Main(string[] args) { String foo = "123"; using (StringBuilder sb = new StringBuilder(foo)) // also sb isn''t disposable, so there will be error { sb.Append("456"); foo = sb.ToString(); } Console.WriteLine(foo); Console.ReadKey(); }

Por qué no debería simplemente usar

+=

Editar: Ok, ahora sé cómo volver a utilizar una instancia de StringBuilder (todavía no sé si esto es correcto con los estándares de código), pero no vale la pena usarlo con una sola string , ¿no es así?


La razón es porque las strings son inmutables. Cuando concatena una string , crea una nueva string . Entonces, cuando necesitas concatenar muchas strings , creas muchos objects . Esto no cuesta mucho en términos de memoria, ya que cada string se usa una vez. Pero da trabajo extra para el GC .

Sin embargo, StringBuilder utiliza el mismo object cada vez, pero lo hace a expensas de la facilidad de uso.


Una string es una clase inmutable . No puedes modificarlo, solo crear nuevas strings .

Entonces cuando escribes result += a; tiene tres strings separadas en la memoria en ese punto: a , el valor anterior del result y el nuevo valor. Por supuesto, esto está absolutamente bien si solo concatena un número limitado de strings . Si haces eso en un bucle for iterando sobre una colección grande, puede convertirse en un problema.

La clase StringBuilder ofrece un mejor rendimiento en estos casos. En lugar de crear nuevas strings para almacenar el resultado de la concatenación, utiliza el mismo objeto. Entonces, si usas stringBuilder.Append(a); nunca tiene el equivalente del "valor anterior de result ".

Esta eficiencia de memoria viene con un precio, por supuesto. Cuando solo concatena una pequeña cantidad de strings un StringBuilder suele ser menos eficiente en cuanto a la velocidad, ya que tenía más sobrecarga en comparación con la clase de string inmutable.

Una cosa a tener en cuenta es que cuando necesita las cadenas intermedias, StringBuilder puede volverse menos eficiente ya que al llamar a .ToString() crea una nueva copia de la string .