web-dev-qa-db-ja.com

.NETのStringBuilderのコンテンツをクリアする最良の方法

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をクリアするとき、2つの可能性を考えることができます。

sb = new StringBuilder();

または

sb.Length = 0;

それをクリアする最良の方法とその理由は何ですか?

ありがとうございました。

編集:現在の.NET 3.5バージョンを使用します。

68
David Espart

.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バージョンを優先して拡張メソッドを廃止できます。

[〜#〜] update [〜#〜]:容量をゼロに設定することはおそらく良い考えではありません。同じインスタンスを再利用する場合、ビルダーに追加するときに再割り当てが保証されます。ただし、Builderのインスタンスのメモリは、Capacityを非常に小さな値(1など)に設定するまで解放されません。 Capacityプロパティのデフォルト値は16です。16の使用を検討するか、または(効率は悪いですが)容量を2回設定することを検討してください。

  • メモリをクリアするには、1または0に設定します
  • 元の容量値(16とは異なる場合があります)に設定して、復元します。
67
Mike Hofer

.NET 4.0ではsb.Clear()を呼び出すことができますが、古いバージョンでは_sb.Length = 0_を設定する必要があります。

Clear()メソッドは.NET 4.0で追加されました。

28
GraemeF

新しいStringBuilderを作成します。古いものは、それに関連するリソース(たとえば、最大長のバッファー)を保持します。これは、ガベージコレクトされるのが最適です。

15
Paul Sonier

あなたは時期尚早な最適化を行っていると思います。

私はsb.Length=0;は、GCが最終的に収集するために別のオブジェクトを作成し、別のオブジェクトを脇に置くのを防ぐための最速の方法です。

新しいStringBuilderを作成することは、メモリの問題に最適です。 sb.Lengthが速度の問題に最適です。

10
Earlz

[〜#〜] msdn [〜#〜] のコミュニティコンテンツから:

ストリングビルダーを破壊せずに効果的にクリアするには、次を使用します。

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

これにより、両方のコンテンツが破壊され、ゼロにサイズ変更されます。前述のように、サイズは小規模なアプリケーションに影響を与える可能性があります。

10

.NET Framework 4では、StringBuilderクラスに新しいメソッドが導入されました。メソッド名は「Clear」です。このメソッドは、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());
5
Jayesh Sorathia

メモリ使用量を削減する場合は、CLRプロファイラーを使用して、上記で説明したメソッドを使用して、ライフサイクルを通じてStringBuilderオブジェクトが使用しているメモリ量を確認します。次に、選択したオプションがニーズに合っており、必要なリソースを解放していることを確認できます。

2
Kim R

これをクリアする最善の方法は、sb = new StringBuilder();を使用することです。そうは言っても、新しい文字列ビルダーオブジェクトをすべて作成した方が良いと思います。

[〜#〜] edit [〜#〜]

これが最善の解決策であることは言うまでもないことです。

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);
1
Matt Grande
// 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;
}
0
PJJ

C#In A NutshellStringBuilderの内容をクリアするには、2つの方法があります。

  1. Lengthをゼロに設定します:

    StringBuilderのLengthzeroに設定しても、内部容量は縮小しません。したがって、StringBuilderに以前に100万文字が含まれていた場合、Lengthをゼロにした後も引き続き約2 MBのメモリを占有します。

  2. 新しいインスタンスを作成します:

    あなたがしたい場合は release the memory、新しいStringBuilderを作成し、古いStringBuilderをスコープからドロップ(およびガベージコレクション)できるようにする必要があります。このアプローチを使用すると、前のアイテムの問題を解決できます。

0
Sina Lotfi

Clear()メソッドを呼び出すだけでlength = 0に設定します。メモリを節約したい場合は、Capacity = 0に設定することもできます。

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

参照:In referencesource.Microsoft.com

0
MaxJ