以前に文字列を + で結合する場合と StringBuilder で Append する場合どちらが速いかという話をどこかで見た記憶があります。その記憶では 10 回くらい結合するなら StringBuilder、それ未満なら + が速いとされていた気がします。
今、試したらどうなるかと思い雑に比べてみました。
■ 結果は条件や運によって変わります
今回の結果は一例です。どの環境でも同じになるというものではありません。
■ 結果
.NET Core では文字列を 8 ~ 11 回、.NET Framework では 5 ~ 8 回結合するのを 200,000 回繰り返し、+ と StringBuilder のどちらが速かったか試しました。各、文字列の結合回数ごとに 10 回検証し勝敗を記録しました。
.NET Core
結合回数 | 8 | 9 | 10 | 11 |
---|---|---|---|---|
+ 結合 | 9 | 4 | 2 | 0 |
StringBuilder | 1 | 6 | 8 | 10 |
.NET Framework
結合回数 | 5 | 6 | 7 | 8 |
---|---|---|---|---|
+ 結合 | 9 | 1 | 7 | 0 |
StringBuilder | 1 | 9 | 3 | 10 |
■ まとめ
文字列を結合する回数が、7 ~ 8 回以下の場合は + が良く、それ以上の場合は StringBuilder を使うのがまあまあ良さそうです。
概ね以前に見かけた記憶と変わっていない感じです。
検証コード
var sw1 = new Stopwatch(); var sw2 = new Stopwatch(); var length = 0; var m = DateTime.Now.Millisecond; var rand = new Random(m); var data = Enumerable.Range(0, 11).Selec(_ => $"{rand.Next()}\n").ToArray(); f(); sw1.Reset(); sw2.Reset(); for (var i = 0; i < 200000; ++i) length +=f(); Console.WriteLine($"+ {sw1ElapsedTicks}"); Console.WriteLine($"Append {sw2ElapsedTicks}"); return length; int f() { string str1 = null, str2 = null; { sw1.Start(); string str = null; foreach (var datum in data) str += datum; sw1.Stop(); str1 = str; } { sw2.Start(); var str = new System.Text.StringBuilder(); foreach (var datum in data) str.Append(datum); str2 = str.ToString(); sw2.Stop(); } return str1.Length + str2.Length; }