質問
StringBuilderの利点を理解しています。
ただし、2つの文字列を連結する場合は、StringBuilderを使用せずに行う方が良い(高速)と想定します。これは正しいですか?
StringBuilderを使用すると、どの時点(文字列の数)で改善されますか?
解決
マイクロ最適化劇場の悲劇を読むことをお勧めします、ジェフ・アトウッド著。
単純連結、StringBuilder、その他のメソッドを処理します。
今、あなたがいくつかの数字とグラフを見たいなら、リンクをたどってください;)
他のヒント
ただし、2を連結する場合 文字列、それから私はそれが なしで行う方が良い(速い) StringBuilder。これは正しいですか?
それは確かに正しいです。正確に説明されている理由を見つけることができます:
http://www.yoda.arachsys.com/csharp/stringbuilder.html
まとめ:文字列を一度に連結できるようになった場合
var result = a + " " + b + " " + c + ..
StringBuilderを使用せずにコピーを作成することをお勧めします(結果の文字列の長さは事前に計算されます)。
次のような構造の場合
var result = a;
result += " ";
result += b;
result += " ";
result += c;
..
毎回新しいオブジェクトが作成されるため、StringBuilderを検討する必要があります。
最後に、記事はこれらの経験則をまとめています:
経験則
したがって、StringBuilderを使用する必要があるのは、 そして、いつ文字列を使用する必要があります 連結演算子?
次の場合にStringBuilderを確実に使用する あなたは非自明に連結しています ループ-特にわからない場合 確かに(コンパイル時に)いくつ 繰り返しを行います ループ。たとえば、ファイルを読み込む 一度にキャラクター、 + =演算子を使用した文字列 潜在的にパフォーマンス自殺です。
連結を確実に使用する 可能な場合の演算子 必要なすべてを指定する 1つのステートメントに連結されます。 (もし、あんたが 物事の配列を持っています 連結、呼び出しを検討 String.Concat明示的に-または String.Join(区切り文字が必要な場合)。
リテラルを分割することを恐れないでください いくつかの連結ビットに- 結果は同じになります。あなたが助けることができます 長いリテラルを壊すことによる読みやすさ たとえば、いくつかの行に パフォーマンスに害はありません。
中間結果が必要な場合 何かの連結の 次の反復を供給すること以外 連結の場合、StringBuilderは お手伝いします。たとえば、 あなたは最初からフルネームを作り上げます 名前と姓を追加してから、 3番目の情報( ニックネーム、多分)最後まで、あなたは StringBuilderを使用することによるメリットのみ (名+ 姓)他の目的の文字列 (作成する例で行うように Personオブジェクト)。
連結がいくつかある場合 し、あなたは本当にそれらをやりたい 別のステートメントで、それはしません どちらに行くかは本当に重要です。どっち より効率的な方法はに依存します 連結の数サイズ 関係する文字列、およびその順序 それらは連結されています。本当に そのコードは パフォーマンスのボトルネック、プロファイル、または 両方の方法でベンチマークします。
System.Stringは不変オブジェクトです。つまり、コンテンツを変更するたびに新しい文字列が割り当てられるため、時間がかかります(そしてメモリが必要ですか?)。 StringBuilderを使用すると、新しいコンテンツを割り当てることなく、オブジェクトの実際のコンテンツを変更できます。
したがって、文字列に多くの変更を加える必要がある場合は、StringBuilderを使用します。
実際には... 大きな文字列を連結する場合、またはループのように多くの連結がある場合は、StringBuilderを使用する必要があります。
決定的な答えはなく、経験則のみです。私の個人的なルールは次のようになります:
- ループで連結する場合は、常に
StringBuilder
を使用します。 - 文字列が大きい場合は、常に
StringBuilder
を使用します。 - 連結コードが画面上で整理されていて読みやすい場合は、おそらく大丈夫です。
そうでない場合は、StringBuilder
を使用します。
言い換えると
その後、3つまで、それ以上でもそれ以下でも数えます。 3は数えるべき数であり、数えられる数は3である。 4つは数えず、2つも数えません。ただし、3つに進む場合を除きます。 3番目の数字である3番目に到達したら、アンティオキアの聖なる手G弾をロブベストします
通常、3つ以上の文字列が連結されるコードブロックには文字列ビルダーを使用します。
- ループで文字列を連結する場合、通常の文字列の代わりにStringBuilderの使用を検討する必要があります
- 単一の連結の場合、実行時間の違いがまったく表示されない場合があります
要点を証明する簡単なテストアプリを次に示します。
class Program
{
static void Main(string[] args)
{
const int testLength = 30000;
var StartTime = DateTime.Now;
//TEST 1 - String
StartTime = DateTime.Now;
String tString = "test string";
for (int i = 0; i < testLength; i++)
{
tString += i.ToString();
}
Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
//result: 2000 ms
//TEST 2 - StringBuilder
StartTime = DateTime.Now;
StringBuilder tSB = new StringBuilder("test string");
for (int i = 0; i < testLength; i++)
{
tSB.Append(i.ToString());
}
Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
//result: 4 ms
Console.ReadLine();
}
}
結果:
-
30'000回の繰り返し
- 文字列-2000ミリ秒
- StringBuilder-4ミリ秒
-
1000回の反復
- 文字列-2ミリ秒
- StringBuilder-1ミリ秒
-
500回の反復
- 文字列-0ミリ秒
- StringBuilder-0ミリ秒
しかし、2つの文字列を連結したい場合は、StringBuilderを使用せずに連結した方が良いと思います。これは正しいですか?
はい。しかし、もっと重要なのは、そのような状況でバニラ String
を使用する方がはるかに読みやすいことです。一方、ループで使用することは理にかなっており、連結と同じくらい読みやすくなります。
特定の数の連結をしきい値として引用する経験則に注意してください。ループ(およびループのみ)で使用することは、おそらく同じように便利で、覚えやすく、より意味があります。
物理的に連結数(a + b + c ...)を入力できる限り、大きな違いはありません。 Nの2乗(N = 10)は100倍の減速であり、それほど悪くないはずです。
大きな問題は、何百もの文字列を連結する場合です。 N = 100では、10000X倍の速度低下が発生します。これはかなり悪いです。
使用するタイミングと使用しないタイミングの間に細かい境界線があるとは思わない。もちろん、誰かが黄金の条件を明らかにするためにいくつかの広範なテストを実行していない限り。
私にとっては、2つの巨大な文字列を連結するだけならStringBuilderは使用しません。不確定なカウントのループがある場合は、ループが小さなカウントであっても、そうなる可能性があります。
単一の連結は、StringBuilderを使用する価値はありません。通常、経験則として5つの連結を使用しました。
StringBuilder クラスは、変更可能な文字列の操作を可能にする一連のメソッドを開発者に提供します。新しいオブジェクトを作成せずに文字列を変更する場合に使用できます。通常の文字列連結のオーバーヘッドまたはボトルネックの問題。
StringBuilder クラスを使用すると、ループ内で多くの文字列を連結する際のパフォーマンスが向上します。
以下は、.NETのStringBuilderクラスを使用して文字列を操作するために実行できるいくつかの操作のリストです
追加:現在のStringBuilderの最後に情報を追加します。
AppendFormat :文字列で渡された書式指定子を書式付きテキストに置き換えます。
挿入:現在のStringBuilderの指定されたインデックスに文字列またはオブジェクトを挿入します。
削除:指定した文字数を現在のStringBuilderから削除します。
置換:指定したインデックスの指定した文字を置換します。