2009-11-10 11 views
63

Me gustaría preguntar cuál cree que es la mejor manera (dura menos/consume menos recursos) para borrar los contenidos con el fin de reutilizar un StringBuilder. Imagine el siguiente escenario:mejor manera de borrar contenido de .NET's StringBuilder

StringBuilder sb = new StringBuilder(); 
foreach(var whatever in whateverlist) 
{ 
    sb.Append("{0}", whatever); 
} 

//Perform some stuff with sb 

//Clear stringbuilder here 

//Populate stringbuilder again to perform more actions 
foreach(var whatever2 in whateverlist2) 
{ 
    sb.Append("{0}", whatever2); 
} 

Y cuando despeje StringBuilder puedo pensar en dos posibilidades:

sb = new StringBuilder(); 

o

sb.Length = 0; 

¿Cuál es la mejor manera de limpiar y por qué?

Gracias.

EDIT: con la versión actual .NET 3.5.

+4

No es una respuesta, pero interesante de leer: http://bobondevelopment.com/2007/06/11/three-ways-to-clear-a-stringbuilder/ –

+1

¿Cuál es la razón por la que no se incluye el método StringBuilder.Clear() como alternativa ? –

+0

@Rune: C# 4.0 aún no ha salido, solo está en 4.0. En MSDN dice: Compatible con: 4. – jcollum

Respuesta

60

Si está haciendo esto en .NET 2.0 o 3.5, escribir un método de extensión de hacerlo de esta manera:

/// <summary> 
///  Clears the contents of the string builder. 
/// </summary> 
/// <param name="value"> 
///  The <see cref="StringBuilder"/> to clear. 
/// </param> 
public static void Clear(this StringBuilder value) 
{ 
    value.Length = 0; 
    value.Capacity = 0; 
} 

A continuación, puede borrar de esta manera:

someStringBuilder.Clear(); 

Entonces, cuando 4.0 sale, puede zanja su método de extensión en favor de la versión 4.0.

ACTUALIZACIÓN: Probablemente no sea una buena idea establecer la capacidad en cero. Eso garantizará reasignaciones cuando se agrega al constructor, si está reutilizando la misma instancia. Sin embargo, la memoria en la instancia del generador no se libera hasta que configura la Capacidad en un valor muy pequeño (como 1). El valor predeterminado de la propiedad de la capacidad es 16. Es posible que desee considerar el uso de 16, o (aunque es menos eficiente) el establecimiento de la capacidad dos veces:

  • ajusta a 1 o cero para borrar la memoria
  • Conjunto a su valor de Capacidad original (que puede diferir de 16) para restaurarlo.
+0

Método ordenado. Justo lo que estaba buscando. – abhi

+12

No recomendaría borrar la capacidad, excepto cuando se sabe que 'StringBuilder' ha retenido algo * inusualmente * grande. Especialmente en versiones anteriores de .net, si uno construye repetidamente cadenas de más de 42,500 caracteres, borrar el búfer después de cada cadena hará que se asignen objetos adicionales en el Montículo de objetos grandes cada vez que el búfer tenga que volver a crecer. Eso es una mala cosa – supercat

+2

Establecer la capacidad en 0 es una idea interesante. Cuando solo utiliza Borrar o simplemente establece la longitud en 0, se puede producir una pérdida de memoria cuando se usa Insertar() repetidamente, porque la Capacidad sigue creciendo a pesar del Despeje. (vea mi pregunta: http://stackoverflow.com/questions/29574469/memory-leak-in-stringbuilder-when-using-insert-and-clear –

15

Crea el nuevo StringBuilder. El anterior mantiene los recursos asociados con él (el búfer de longitud máxima, por ejemplo) que es mejor simplemente recoger la basura.

28

En .NET 4.0 puede llamar al sb.Clear(), pero en versiones anteriores debe establecer sb.Length = 0.

El método Clear() se agregó en .NET 4.0.

+1

Establezca la capacidad en cero también ... –

+12

Si está reutilizando, ¿no le gustaría reutilizar el búfer? – GraemeF

+2

depende de la varianza de la cantidad de cadena creada la primera vez en comparación con la cadena creada la segunda vez. O al menos yo pensaría que – Earlz

10

Creo que está realizando una optimización prematura.

Apuesto a que hacer sb.Length=0; sería el más rápido para evitar la creación de otro objeto y dejar de lado otro objeto para que el GC eventualmente lo recolecte.

Creo que la creación de un nuevo StringBuilder sería la mejor opción para la memoria. y el establecimiento de sb.Length sería la mejor oportunidad para las preocupaciones de velocidad ..

10

De Contenido de la comunidad en MSDN:

Para limpiar eficazmente su StringBuilder sin destruirlo uso:

someStringBuilder.length = 0; 
someStringBuilder.capacity = 0; 

Esto destruye tanto su contenido como lo cambian a cero. Como se indicó anteriormente, despejar el tamaño puede afectar aplicaciones más pequeñas .

1

Yo diría que la mejor manera de borrarlo es usar sb = new StringBuilder();. Una vez dicho esto, creo que sería aún mejor si crearas un nuevo objeto generador de cadenas por completo.

EDITAR

espero que no hace falta decir que esta es la mejor solución.

public StringBuilder MakeString(IEnumerable<CoolType> list) 
{ 
    StringBuilder sb = new StringBuilder(); 

    foreach(var whatever in list) 
    { 
     sb.Append("{0}", whatever); 
    } 
} 

var sb = MakeString(whateverList); 
// Do stuff 
// Clear stuff 
sb = MakeString(whateverList2); 
+5

sb = new StringBuilder() está creando un nuevo objeto generador de cadenas. –

+0

Haciendo eso, hace un nuevo objeto constructor de cadenas por completo. –

+0

Creo que Matt significa declarar una nueva variable PARA el nuevo 'StringBuilder'. –

2

Si usted está buscando para reducir el uso de memoria me gustaría utilizar el CLR Profiler para comprobar la cantidad de memoria sus objetos StringBuilder están utilizando a través de su ciclo de vida utilizando los métodos que otros han descritos anteriormente. Luego puede asegurarse de que la opción que elija sea adecuada para sus necesidades y libere los recursos que necesita.

4

En .NET Framework 4 se introdujeron nuevos métodos en la clase StringBuilder. El nombre del método es "Borrar". Este método le ayuda a borrar o eliminar valores o datos de los objetos StringBuilder.

Aquí hay un ejemplo de esto.

System.Text.StringBuilder objSB = new System.Text.StringBuilder(); 
    //Append values 
    objSB.Append("This is .Net Blog."); 
    objSB.Append("You can get latest C# Tips over here."); 

    //Display on screen 
    Response.Write(objSB.ToString()); 
    Response.Write("<br/><br/>"); 

    //Clear object using Clear method 
    objSB.Clear(); 

    //Append another values 
    objSB.Append("This blog is very useful for .Net Beginners"); 

    Response.Write("After Clear<br/><br/>"); 
    //Display on screen 
    Response.Write(objSB.ToString()); 
0

Sólo tiene que llamar Clear() método que acabamos de ajustar la longitud = 0, Podemos establecer Capacidad = 0 también, si queremos ahorrar memoria

public StringBuilder Clear() { 
     this.Length = 0; 
     return this; 
} 

Ref: En referencesource.microsoft.com

Cuestiones relacionadas