views:

737

answers:

7

Hello, 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.

+8  A: 

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.

McWafflestix
+8  A: 

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.

GraemeF
Set capacity to zero also...
Philip Wallace
If you're reusing it wouldn't you want to reuse the buffer?
GraemeF
depends on the variance of how much big the string created the first time compared to the string created the second time.. Or at least I would think so
Earlz
+5  A: 

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..

Earlz
+8  A: 

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.

Yuriy Faktorovich
A: 

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);
Matt Grande
sb = new StringBuilder() IS making a new string builder object.
Philip Wallace
Doing that DOES make a new string builder object altogether.
McWafflestix
I think Matt means declare a new variable FOR the new `StringBuilder`.
Dan Tao
Sorry, to clairify I'm recommending doing something like this: var wellNamedStringBuilder = new StringBuilder();
Matt Grande
+16  A: 

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.
Mike Hofer
Neat Method. Just what I was looking for.
abhi
+1  A: 

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.

Kim R