best way to clear contents of .NET's StringBuilder

I would like to ask what you think is the best way (lasts less / consumes less resources) to clear the contents in order to reuse a StringBuilder. Imagine the following scenario:

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

And when clearing StringBuilder I can think of two possibilities:

sb = new StringBuilder();

or

sb.Length = 0;

What is the best way to clear it and why?

Thank you.

EDIT: I ment with current .NET 3.5 version.

77727 次浏览

Create the new StringBuilder. The old one maintains resources associated with it (buffer of maximum length, for example) that are best just garbage collected away.

In .NET 4.0 you can call sb.Clear() but in older versions you should set sb.Length = 0.

The Clear() method was added in .NET 4.0.

I think you are doing premature optimization.

I would bet that doing sb.Length=0; would be the fastest to keep from creating another object and placing another object aside for GC to eventually collect.

I think creating a new StringBuilder would be the best shot for memory concerns. and setting sb.Length would be the best shot for speed concerns..

From Community Content on MSDN:

To effectively clear your stringbuilder without destroying it use:

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

This destroys both its contents and resizes it to zero. As noted above clear the size can impact smaller applications.

I'd say the best way to clear it is to use sb = new StringBuilder();. That being said, I think it'd be even better if you made a new string builder object altogether.

EDIT

I hope it goes without saying that this is the best solution.

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

If you're doing this in .NET 2.0 or 3.5, write an extension method to do it like this:

/// <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;
}

Then, you can clear it like this:

someStringBuilder.Clear();

Then, when 4.0 comes out, you can ditch your extension method in favor of the 4.0 version.

UPDATE: It's probably not a good idea to set Capacity to zero. That will guarantee reallocations when you append to the builder, if you're reusing the same instance. However, the memory in the instance of the builder is not released until you set the Capacity to a very small value (such as 1). The default value of the Capacity property is 16. You might want to consider using 16, or (though it's less efficient) setting the capacity twice:

  • Set it to 1 or zero to clear the memory
  • Set it to your original Capacity value (which may differ from 16) to restore it.

If you are looking to reduce memory usage I would use the CLR Profiler to check how much memory your StringBuilder objects are using through their lifecycle using the methods others have described above. Then you can satisfy yourself that the option you choose is suitable for your needs and is releasing the resources you need it to.

In .NET Framework 4 new methods were introduced in StringBuilder class. Method name is "Clear". This method helps you to clear or remove values or data from StringBuilder objects.

Here is example for this.

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

Just call Clear() method just set length = 0 , We can set Capacity = 0 also, if we want to save memory

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

Ref: In referencesource.microsoft.com

// P.S. to be ultra efficient
// make a good guess at the initial allocation too !!!!
int PerWhatever_SizeEstimate = 4; // a guess of average length... you known your data
StringBuilder sb = new StringBuilder( whateverlist.Length * PerWhatever_SizeEstimate);


// reallocation needed?
// if you want to be efficient speed and memory wise...
sb.Length = 0;  // rest internal index but don't release/resize memory
// if a ...BIG... difference in size
if( whatever2.Length < whatever.Length * 2/3
|| whatever2.Length > whatever.Length * 1.5)
{
//scale capacity appropriately
sb.Capaciy = sb.Capacity * whatever2.Length / whatever.Length;
}

C# In A Nutshell To clear the contents of a StringBuilder, there are two ways:

  1. Set its Length to zero:

    Setting a StringBuilder’s Length to zero doesn’t shrink its internal capacity. So, if the StringBuilder previously contained one million characters, it will continue to occupy around 2 MB of memory after zeroing its Length.

  2. Instantiate a new one:

    If you want to release the memory, you must create a new StringBuilder and allow the old one to drop out of scope (and be garbage collected), with this approach you can solve the previous item problem.