清除.NET的StringBuilder内容的最佳方法

时间:2009-11-10 16:55:38

标签: c# .net optimization .net-3.5

我想问一下你认为最好的方法(持续时间更少/消耗更少的资源)来清除内容以重用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);
}

清理StringBuilder时,我可以想到两种可能性:

sb = new StringBuilder();

sb.Length = 0;

清除它的最佳方法是什么?为什么?

谢谢。

编辑:我使用当前的.NET 3.5版本。

11 个答案:

答案 0 :(得分:66)

如果您在.NET 2.0或3.5中执行此操作,请编写一个扩展方法来执行此操作:

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

然后,您可以这样清除它:

someStringBuilder.Clear();

然后,当4.0出来时,您可以放弃扩展方法,转而支持4.0版本。

更新:将Capacity设置为零可能不是一个好主意。如果您重复使用同一个实例,那么当您追加到构建器时,这将保证重新分配。但是,在将Capacity设置为非常小的值(例如1)之前,不会释放构建器实例中的内存。 Capacity属性的默认值为16.您可能要考虑使用16,或者(虽然效率较低)将容量设置两次:

  • 将其设置为1或零以清除内存
  • 将其设置为原始容量值(可能与16不同)以恢复它。

答案 1 :(得分:28)

在.NET 4.0中,您可以致电sb.Clear(),但在旧版本中,您应该设置sb.Length = 0

在.NET 4.0中添加了Clear()方法。

答案 2 :(得分:15)

创建新的StringBuilder。旧的维护与之相关的资源(例如,最大长度的缓冲区),这些资源最好只是垃圾收集。

答案 3 :(得分:10)

我认为你正在做过早的优化。

我敢打赌,做sb.Length=0;是最快的,不会创建另一个对象,并放置另一个对象,以便最终收集GC。

我认为创建一个新的StringBuilder将是内存问题的最佳选择。设置sb.Length对于速度问题来说是最好的选择。

答案 4 :(得分:10)

来自MSDN上的社区内容:

  

有效清除你的   stringbuilder没有破坏它   使用方法:

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

这会摧毁它的内容和   将其调整为零。如上所述   清除尺寸可以影响较小   应用

答案 5 :(得分:5)

在.NET Framework 4中,StringBuilder类中引入了新方法。方法名称为“清除”。此方法可帮助您清除或删除StringBuilder个对象中的值或数据。

以下是此示例。

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

答案 6 :(得分:2)

如果您希望减少内存使用量,我会使用CLR Profiler来检查StringBuilder对象在其生命周期中使用上述其他方法所使用的内存量。然后,您可以确信您选择的选项适合您的需求,并释放您需要的资源。

答案 7 :(得分:1)

我想说清除它的最好方法是使用sb = new StringBuilder();。话虽如此,我认为如果你完全制作一个新的字符串构建器对象会更好。

修改

我希望不用说这是最好的解决方案。

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

答案 8 :(得分:0)

只需调用Clear()方法,只需设置length = 0, 如果我们想节省内存,我们也可以设置Capacity = 0

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

参考:referencesource.microsoft.com

答案 9 :(得分:0)

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

答案 10 :(得分:0)

C# In A Nutshell要清除StringBuilder的内容,有两种方法:

  1. 将其Length设置为零:
      

    将StringBuilder的Length设置为zero不会减少其内部容量。因此,如果StringBuilder以前包含一百万个字符,则将其Length设置为零后,它将继续占据大约2 MB的内存。

  2. 实例化一个新的:
      

    如果您想release the memory,则必须创建一个新的StringBuilder并允许旧的StringBuilder退出作用域(并进行垃圾回收),用这种方法可以解决上一个项目的问题。