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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1709471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 20:09:51  来源:igfitidea点击:

best way to clear contents of .NET's StringBuilder

c#.netoptimization.net-3.5

提问by David Espart

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 的最佳方法是什么(持续时间更少/消耗更少资源)。想象以下场景:

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:

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

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.

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

采纳答案by Mike Hofer

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

如果您在 .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;
}

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.

然后,当 4.0 出现时,您可以放弃扩展方法,转而使用 4.0 版本。

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:

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

  • 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.
  • 将其设置为 1 或零以清除内存
  • 将其设置为您的原始容量值(可能不同于 16)以恢复它。

回答by Paul Sonier

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.

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

回答by GraemeF

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

在 .NET 4.0 中你可以调用,sb.Clear()但在旧版本中你应该设置sb.Length = 0.

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

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

回答by Earlz

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.

我敢打赌,这样做sb.Length=0;是避免创建另一个对象并将另一个对象放在一边以供 GC 最终收集的最快方法。

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

我认为创建一个新的 StringBuilder 将是解决内存问题的最佳选择。并且设置sb.Length将是速度问题的最佳选择。

回答by Yuriy Faktorovich

From Community Content on MSDN:

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

要有效地清除 stringbuilder 而不破坏它,请使用:

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

这会破坏其内容并将其大小调整为零。如上所述,显然尺寸会影响较小的应用程序。

回答by Matt Grande

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.

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

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

回答by Kim R

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.

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

回答by Jayesh Sorathia

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

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

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

回答by Max CHien

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

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

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

Ref: In referencesource.microsoft.com

参考:在referencesource.microsoft.com

回答by PJJ

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