は文字列です。フォーマットで効率的としてStringBuilder
-
08-06-2019 - |
質問
といstringbuilderクライアントまで、フルのC#とは:
StringBuilder sb = new StringBuilder();
string cat = "cat";
sb.Append("the ").Append(cat).(" in the hat");
string s = sb.ToString();
それとも、それとして効率の高いあるいは他のより効率的な
string cat = "cat";
string s = String.Format("The {0} in the hat", cat);
その場合、いかがでしょうか?
編集
その後興味深い応答を実感していただろうして少し明かったと思います。んくうえでしたより迅速で列を文字列では迅速で 注入 一つの文字列を得るというものである。
両方の場合、上記したいの注入を一つ以上の文字列の定義済みのテンプレート文字列になります。
しまいまして申し訳ありません混乱
解決
注意: この答えを書いた時。純2.0したが、現在のバージョン。この手法が通用しなくなる。
String.Format
を採用 StringBuilder
内部的に
public static string Format(IFormatProvider provider, string format, params object[] args)
{
if ((format == null) || (args == null))
{
throw new ArgumentNullException((format == null) ? "format" : "args");
}
StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
builder.AppendFormat(provider, format, args);
return builder.ToString();
}
上記のコードは、スニペットからmscorlib、問題は StringBuilder.Append()
高速 StringBuilder.AppendFormat()
"?
なベンチマークの思いと言えるサンプルコードが実行をより迅速に利用 .Append()
.でも、ベンチマーキングやプロファイリングの取得を適切に比較です。
このchapジェリー-ディクソンとしたベンチマーキング:
http://jdixon.dotnetdevelopersjournal.com/string_concatenation_stringbuilder_and_stringformat.htm
更新:
残念なのは、上記のリンクです。しかしいコピー、機械:
末日でか文字列のフォーマットするという繰り返し、やっているいくつかの深刻なテキスト処理100以上のメガバイトのテキストかれているというユーザがクリックするとボタンもしばしば。ない限りやっている大きなバッチ処理ジョブんで貼った文字列になります。形式でエイズコードを読むした疑いがある場合、ケボトルネックをわるプロファイラにコードを見つのプラットフォームに対応
他のヒント
から MSDN書:
の連結運転のための文字列またはStringBuilderオブジェクトに依存してからメモリ割り当てが発生します。文字列の連結操作を常にメモリ割り当ては、StringBuilder連結運転のみ割り当てメモリの場合、StringBuilderオブジェクトのバッファが小さすぎて、新データです。その結果、文字列のクラスが望ましいため連結の操作の場合枚数を固定したStringオブジェクトの連結されている.その場合は、個別に連結した業務な組み合わせて単操作のコンパイラです。A StringBuilderオブジェクトが好ましいため連結の操作の場合は任意の数の文字列を処理してくれるかどうかは,;例えば、ループconcatenates乱数の文字列ユーザの入力します。
を行ったあるアットホームな性能ベンチマークは、100,000業務の平均値で約10、最初の方法(文字列ビルダー)のほぼ半分の時間の秒(文字列形式)になります。
そのため、このピエーヴェエマヌエーレに位置しています。があった場合は、共通の操作を使用する場合がありま最初の方法です。
私は期待 文字列になります。形式 に遅くなることで解析、文字列 その 連結します。
カップルの注意
- 形式 はユーザーの目に見えない文字列をプロの用途この局在のバグ
- がわかっている場合は、それを長の結果の文字列を事前に利用 StringBuilder(Int32) コンストラクタpredefineの能力
が文字列になります。形式になりそうだと思いますが、ここでは、再試験の6年後にNet45.
Concatも最速なもので30%以上のもの。StringBuilderやフォーマットにより異なりほとんど5-10%.か変動の20%を試験しない。
ミリ秒単位、百万反復回数:
- 連結:367
- 新stringBuilderの各キー:452
- キャッシュStringBuilder:419
- 文字列になります。フォーマット:475
はかりの性能の違いはなびなを入力して検索することができま書く最も簡単な読みコードできます。るために自分がよくなっていない a + b + c
.
const int iterations=1000000;
var keyprefix= this.GetType().FullName;
var maxkeylength=keyprefix + 1 + 1+ Math.Log10(iterations);
Console.WriteLine("KeyPrefix \"{0}\", Max Key Length {1}",keyprefix, maxkeylength);
var concatkeys= new string[iterations];
var stringbuilderkeys= new string[iterations];
var cachedsbkeys= new string[iterations];
var formatkeys= new string[iterations];
var stopwatch= new System.Diagnostics.Stopwatch();
Console.WriteLine("Concatenation:");
stopwatch.Start();
for(int i=0; i<iterations; i++){
var key1= keyprefix+":" + i.ToString();
concatkeys[i]=key1;
}
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.WriteLine("New stringBuilder for each key:");
stopwatch.Restart();
for(int i=0; i<iterations; i++){
var key2= new StringBuilder(keyprefix).Append(":").Append(i.ToString()).ToString();
stringbuilderkeys[i]= key2;
}
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.WriteLine("Cached StringBuilder:");
var cachedSB= new StringBuilder(maxkeylength);
stopwatch.Restart();
for(int i=0; i<iterations; i++){
var key2b= cachedSB.Clear().Append(keyprefix).Append(":").Append(i.ToString()).ToString();
cachedsbkeys[i]= key2b;
}
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.WriteLine("string.Format");
stopwatch.Restart();
for(int i=0; i<iterations; i++){
var key3= string.Format("{0}:{1}", keyprefix,i.ToString());
formatkeys[i]= key3;
}
Console.WriteLine(stopwatch.ElapsedMilliseconds);
var referToTheComputedValuesSoCompilerCantOptimiseTheLoopsAway= concatkeys.Union(stringbuilderkeys).Union(cachedsbkeys).Union(formatkeys).LastOrDefault(x=>x[1]=='-');
Console.WriteLine(referToTheComputedValuesSoCompilerCantOptimiseTheLoopsAway);
と思うほとんどの場合このような明確な効率化すべきである最大の懸念です。ませんが粉砕とトンの文字列、またはものための低ッサーを搭載したモバイルデバイスのころなんでみたいという気持ちになりの凹みに走る高速になります。
また、私はビル内の文字列はかなりリニアファッションのいずれかとの直concatenations用StringBuilderることができます。私はこの場合には多数の文字列かんなはダイナミックに変化します。少なかったテキストの静的な、最も重要なことが、それぞれのダイナミックテキスト入している場合であってニーズを更新します。
他方であれば、話は大きなチャンクの静的なテキストや変数な場合でも、ちょっと効率的になると思いは明確だから文字列になります。の形式で使い勝手は大きく変わります。ここを有するものを一つのビットにおけるダイナミックテキストのセンターの4ページの書きします。できや更新をする大きなチャンクのテキストが一つの作品よりも更新三枚で連結す。
文字列になります。の形式で使用 StringBuilder
社内でバーコードリーダを論理的につながるという考えのもとでより少ないものになperformantよりオーバーヘッド。しかし、単純な文字列の連結には最高速を注入する方法が一つの文字列とothers...by 大きな程度です。この証拠を示によりパッケージングコンテストMariani彼の初めて性能をテストす。になることconcatenations...数が文字列の部品が知られている(これに限..き連結千パーツとして---長いも1000パーツ)...いつもよりも早く StringBuilder
または文字列です。形式です。彼が可能になってい単一のメモリ割り当てるシリーズのメモリにコピー。 こちらの の証明
こちらは実際にコードの一部の文字列になります。Concat方法は、最終的にはコFillStringChecked用のポインタをコピーメモリを抽出しを通リフレクタ):
public static string Concat(params string[] values)
{
int totalLength = 0;
if (values == null)
{
throw new ArgumentNullException("values");
}
string[] strArray = new string[values.Length];
for (int i = 0; i < values.Length; i++)
{
string str = values[i];
strArray[i] = (str == null) ? Empty : str;
totalLength += strArray[i].Length;
if (totalLength < 0)
{
throw new OutOfMemoryException();
}
}
return ConcatArray(strArray, totalLength);
}
public static string Concat(string str0, string str1, string str2, string str3)
{
if (((str0 == null) && (str1 == null)) && ((str2 == null) && (str3 == null)))
{
return Empty;
}
if (str0 == null)
{
str0 = Empty;
}
if (str1 == null)
{
str1 = Empty;
}
if (str2 == null)
{
str2 = Empty;
}
if (str3 == null)
{
str3 = Empty;
}
int length = ((str0.Length + str1.Length) + str2.Length) + str3.Length;
string dest = FastAllocateString(length);
FillStringChecked(dest, 0, str0);
FillStringChecked(dest, str0.Length, str1);
FillStringChecked(dest, str0.Length + str1.Length, str2);
FillStringChecked(dest, (str0.Length + str1.Length) + str2.Length, str3);
return dest;
}
private static string ConcatArray(string[] values, int totalLength)
{
string dest = FastAllocateString(totalLength);
int destPos = 0;
for (int i = 0; i < values.Length; i++)
{
FillStringChecked(dest, destPos, values[i]);
destPos += values[i].Length;
}
return dest;
}
private static unsafe void FillStringChecked(string dest, int destPos, string src)
{
int length = src.Length;
if (length > (dest.Length - destPos))
{
throw new IndexOutOfRangeException();
}
fixed (char* chRef = &dest.m_firstChar)
{
fixed (char* chRef2 = &src.m_firstChar)
{
wstrcpy(chRef + destPos, chRef2, length);
}
}
}
そのた:
string what = "cat";
string inthehat = "The " + what + " in the hat!";
楽しめます!
Ohまた、最速することはできない。
string cat = "cat";
string s = "The " + cat + " in the hat";
のです。小さな文字列数concatenations、これは実際の速るだけで追加の文字列です。
String s = "String A" + "String B";
大型の文字列(も非常に大きい文字列)で、そしてより効率的な利用StringBuilder.
両方の場合、上記したいの注入を一つ以上の文字列の定義済みのテンプレート文字列になります。
その場合、私はあなた文字列になります。形式が最も迅速でデザインする正確な目的です。
となります)本利用パターンです。
詳細なベンチマークと string.Join
, string,Concat
や string.Format
で、できるだけ早く送ってくださ 文字列になります。形式のいないのに適した集中的にログイン
私はあなたがいない、文字列になります。方式設計にはなっておりませんので連結したデザインのためのフォーマットの出力各入力します。
String s = String.Format("Today is {0:dd-MMM-yyyy}.", DateTime.Today);