web-dev-qa-db-ja.com

.NET 3.5でStringBuilderを再び空にする方法は?

特定の条件に基づいて文字列値を作成するループがあります。 StringBuilderオブジェクトをループの外側に配置しました。ループ内に新しい行があるたびに、この行に追加されたStringBuilderの値をクリアする必要があります。

それらをクリアするにはどうすればよいですか?

        StringBuilder sb = new StringBuilder();

        foreach (DataRow row in recipientsList.Rows)
        {
            sb.Length = 0;
            sb.Append("<ul>");
            if (row["needsToActivate"] == "1")
            {
                sb.AppendFormat("<li>{0}</li>", getUsersWithoutActivationTemplate());
            }
            if (row["needsToEnterSite"] == "1")
            {
                sb.AppendFormat("<li>{0}</li>", getUsersWithoutEnteringWebsiteForTwoWeeksTemplate());
            }
            if (row["needsPicture"] == "1")
            {
                sb.AppendFormat("<li>{0}</li>", getUsersWithoutPicturesTemplate());
            }
            if (row["needsText"] == "1")
            {
                sb.AppendFormat("<li>{0}</li>", getUsersWithoutTextTemplate());
            }
            if (row["needsCharacteristic"] == "1")
            {
                sb.AppendFormat("<li>{0}</li>", getUsersWithoutCharateristicsTemplate());
            }
            if (row["needsHobby"] == "1")
            {
                sb.AppendFormat("<li>{0}</li>", getUsersWithoutHobbiesTemplate());
            }
            sb.Append("</ul>");
}

受け入れられた回答のあるコード。

19
eugeneK

あなたは簡単にできます。

sb.Length = 0;
50
Alex K.

StringBuilder.Clear();はあなたが望むものです。

13
PhilPursglove

長さを0に設定するか、.Net 4で新しいClear()メソッドを呼び出すことができると思います。

4
Scott

StringBuilderを(.Clear()または.Length = 0で)再利用できますが、本当に最適化したい場合は、最終的な長さを見積もる必要があります。これが反復ごとに少し大きくなる場合、再利用は毎回新しいものを作成するよりも遅くなる可能性があります(より多くのmemを使用します)。

foreach (DataRow row in recipientsList.Rows)
{
    int estimatedLength = 5000; // maybe a calculation based on row-data
    StringBuilder sb = new StringBuilder(estimatedLength);
    ....

}

したがって、ここでの答えはどのようにそれを行うかは正しいですが、最善のアドバイスはそれを行わないです。これはマイクロ最適化であり、ここでは非常に小さなゲインは必要ありません。また、(小さな)余分な複雑さも必要ありません。結果の文字列が非常に大きい場合は、ここで少し最適化できますが、これを習慣にしないでください。

3
Henk Holterman

StringBuilderを次のように定義するとします。StringBuildersb= new StringBuilder();

次のいずれかを実行できます。

Clearメソッドを呼び出します。

for (int i = 0; i < 100; i++)
{
    sb.Clear();
    .. your code here ..
}

長さをゼロに設定します。

for (int i = 0; i < 100; i++)
{
    sb.Length = 0;
    .. your code here ..
}

新しいオブジェクトに設定します。

for (int i = 0; i < 100; i++)
{
    sb = new StringBuilder();
    .. your code here ..
}
3
Jonathan

私も同様の問題に直面しました。

このトリックは私のために働いた

sb.Replace(sb.ToString(), "");

このコードは、文字列全体を""に置き換えます。

0

私が学んだことは

sb.Length = 0;

しかし、私の答えには、メモリを断片化せずにStringBuilderを使用する方法に関するヒントが含まれています。長さをゼロに設定して再利用するように注意しているので、常に再割り当てするわけではありません。さらに一歩進んで、断片化や頻繁な割り当てを減らしてみませんか?

StringBuilder sb = new System.Text.StringBuilder(22_000); // preallocate ~20K

必要なスペースの量がほぼわかる場合は、StringBuilderが使用するスペースを事前に割り当てることを検討してください。コンストラクターで割り当てるスペースの量を指定できるのには理由があります。これにより、パフォーマンスが向上します。 1つの割り当てを一度に行うと、他の割り当てが散在する多くの小さな割り当てよりも高速になります。

そこで、コードを介していくつかのデータを実行し、StringBuilderのサイズを調べ、いくつかの係数を掛けて、それをStringBuilderの初期割り当てサイズとして配置します。

0