rksoftware

Visual Studio とか C# とかが好きです

C# 文字列を連続で結合するときの + と StringBuilder の速さ

以前に文字列を + で結合する場合と StringBuilderAppend する場合どちらが速いかという話をどこかで見た記憶があります。その記憶では 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;
}