StringBuilder.Append Vs StringBuilder.AppendFormat
-
22-08-2019 - |
質問
のかと思っていStringBuilderとんうつくろうと思いました地域で伝えできたらと考えております。
だれを忘れるほコードの読みやすさは、これらは 高速 るのか。
StringBuilder.Append
:
StringBuilder sb = new StringBuilder();
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
StringBuilder.AppendFormat
:
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}----{1}",string1,string2);
解決
することはできないと言いがわからないサイズの string1
や string2
.
を呼び出 AppendFormat
, まpreallocateのバッファ回だされたフォーマット文字列の文字列が挿入され、その後の連結ものと差し込み、バッファです。のための非常に大きな文字列、このことインターネットで提供される以上個別の通話を Append
がの原因となるバッファーを拡大す。
しかし、電話 Append
れないトリガー成長のバッファやチェックが実施されています。の場合は文字列は小さいなバッファの拡大には、それを可能に AppendFormat
でないパフォーマット文字列がないので代替す
より多くのデータが必要な段階では明確にお答え
このあまり議論を利用静的 Concat
方法に String
クラス (ジョンの回答 を使用 AppendWithCapacity
のオーラという言葉が定着した。試験の結果の場合(ばんの特定のフォーマット指定子). String.Concat
も同じことが行われていることでpredetermineの長さの文字列を連結びpreallocateのバッファーとのやや架によるループ構築を通じてのパラメータこの性能を比較することはできジョンの AppendWithCapacity
方法。
は、平野のほか、オペレーターで統を呼び出し String.Concat
鏡の点に注意するすべての追加と同じ表現
// One call to String.Concat.
string result = a + b + c;
ない
// Two calls to String.Concat.
string result = a + b;
result = result + c;
すべての人をコード試験
を実行する必要がありますテストケース 別 運(または少なくとも、GCの測定個別の試験運行).デジタル化できなかった理由はただ、1,000,000、新規作成 StringBuilder
繰り返し処理毎にループごとに一個の試験は、その次の試験ループの回数、 追加 1,000,000 StringBuilder
インスタンスは、GCがありまステップ第二次試験及び妨げ、そのタイミングでした。
他のヒント
casperOneは正しいのです。あなたが特定のしきい値に達すると、Append()
方法はAppendFormat()
よりも遅くなりました。ここで、異なる長さ及び各方法100,000反復の経過ティックは、次のとおり
長さ:1
Append() - 50900
AppendFormat() - 126826
長さ:1000
Append() - 1241938
AppendFormat() - 1337396
長さ:万
Append() - 12482051
AppendFormat() - 12740862
長20,000
Append() - 61029875
AppendFormat() - 60483914
2万近い長さの文字列が導入されると、AppendFormat()
機能はのわずかのアウトパフォームAppend()
ます。
これはなぜ起こるのでしょうか? casperOneの答えを参照してください。
の編集の
私は、Release構成の下で個別にテストをreranし、結果を更新します。
casperOneが全て正確かつそのデータ.しかし、いまことクラスライブラリのための3者の消費を備えています。
ることが一のぶどのデータをいかにして追加し、その利用 StringBuilder.EnsureCapacity くいだけで単一のバッファサイズ変更.
まん すぎ んが、今までの利用 Append
x3う"が"めとして構文解析の文字列形式のトークンの全ての通話は明らかくたくさんありました。
ているので注意してほしいのBCLチームのための一種の"キャッシュされたフォーマッター"まで作成用フォーマット文字列としての再利用を繰り返す。この狂の枠組みを構文解析のフォーマット文字列の各時間で使用します。
編集:大丈夫、私は編集ジョーンズコードや柔軟性に加えて"AppendWithCapacity"の作品だけに必要な能力です。この結果、異なる長さ-長さ1を使って1,000,000回;すべてのその他の長さ使用した100,000.(これだけでも良識ある走ります。) すべての時間でmillis.
残念ながらテーブルやすい仕事です。の長さは1,1000,10000,20000
時間:
- 追加:162,475,7997,17970
- AppendFormat:392,499,8541シリーズ,18993
- AppendWithCapacity:139,189,1558,3085
もしかしながら現実に面したこのAppendFormatビートに追加もっ かった 見AppendWithCapacity選手は非常に充実。
こちらのフルコード:
using System;
using System.Diagnostics;
using System.Text;
public class StringBuilderTest
{
static void Append(string string1, string string2)
{
StringBuilder sb = new StringBuilder();
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
}
static void AppendWithCapacity(string string1, string string2)
{
int capacity = string1.Length + string2.Length + 4;
StringBuilder sb = new StringBuilder(capacity);
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
}
static void AppendFormat(string string1, string string2)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}----{1}", string1, string2);
}
static void Main(string[] args)
{
int size = int.Parse(args[0]);
int iterations = int.Parse(args[1]);
string method = args[2];
Action<string,string> action;
switch (method)
{
case "Append": action = Append; break;
case "AppendWithCapacity": action = AppendWithCapacity; break;
case "AppendFormat": action = AppendFormat; break;
default: throw new ArgumentException();
}
string string1 = new string('x', size);
string string2 = new string('y', size);
// Make sure it's JITted
action(string1, string2);
GC.Collect();
Stopwatch sw = Stopwatch.StartNew();
for (int i=0; i < iterations; i++)
{
action(string1, string2);
}
sw.Stop();
Console.WriteLine("Time: {0}ms", (int) sw.ElapsedMilliseconds);
}
}
Append
には速くになりますほとんどの場合、コンパイラが正しいメソッドを呼び出すことができ、その方法には多くのオーバーロードがありますので。あなたがStrings
を使用しているのでStringBuilder
はString
ためAppend
オーバーロードを使用することができます。
AppendFormat
のString
を取り、その後、フォーマットが解析されなければならないことを意味Object[]
、アレイ内の各Object
はそれがToString'd
内部配列に追加することができる前にStringBuilder's
する必要があります。
注: casperOneのポイントへ - より多くのデータをせずに正確な答えを与えることは困難である。
。 StringBuilder
もカスケード接続している追加されますAppend()
はStringBuilder
自身を返しますので、あなたはこのようなコードを書くことができます:
StringBuilder sb = new StringBuilder();
sb.Append(string1)
.Append("----")
.Append(string2);
クリーン、そして(それは本当にマイクロ最適化だが)、それはあまりIL-コードを生成します。
もちろん、輪郭のそれぞれの場合に確実に知るために。
私はあなたが繰り返しフォーマット文字列を解析していないので、一般的に、それは、元になると思う、と述べたこと。
しかし、その差は非常に小さくなります。あなたが本当にとにかく、ほとんどの場合、AppendFormat
の使用を検討する必要があります。
私はそれが仕事の最低額をしたコールだったと仮定したいです。ただAppendFormatは、文字列置換を行っている文字列を、連結追加します。もちろん、これらの日、あなたが言うことができませんでし...
1が速くなければなりません。だから、そこに余分なステップがあります。
の高速化は、しかし、それは公正な比較ではありません、あなたの場合は1です。あなたはStringBuilder.Append(String.Formatの())VS)(StringBuilder.AppendFormatを依頼する必要があります - 最初のものはより速く内部作業のためにchar配列である。ここで、
。あなたの目のオプションは、しかし、より読みやすいです。