文字列結合のパフォーマンス

いつもお世話になっている++C++;サイトのこちら
https://ufcpp.net/study/csharp/start/improvedinterpolatedstring/

$"{a}.{b}.{c}.{d}";

とかの処理がC#10で速くなったようです。ありがたや。ありがたや。

せっかくなので、どのように動くのか。また、ベンチマークでどうなるのかなどを調べてみました。

単純に、stringを + でつないだ場合と、$”{}”を使った場合で、どのような差がでるか。
まずはベンチマークの結果から。

const int _loopCount = 1_000_000;

[Benchmark]
public int StringPlus4()
{
    int length = 0;
    string a = "yamada";
    string b = "taro";

    for (int i = 0; i < _loopCount; i++)
    {
        string value = a + "." + b + ".";
        length += value.Length;
    }

    return length;
}

[Benchmark]
public int StringPlus5()
{
    int length = 0;
    string a = "yamada";
    string b = "taro";
    string c = "japan";

    for (int i = 0; i < _loopCount; i++)
    {
        string value = a + "." + b + "." + c;
        length += value.Length;
    }

    return length;
}

[Benchmark]
public int DollarFormat4()
{
    int length = 0;
    string a = "yamada";
    string b = "taro";

    for (int i = 0; i < _loopCount; i++)
    {
        string value = $"{a}.{b}.";
        length += value.Length;
    }

    return length;
}

[Benchmark]
public int DollarFormat5()
{
    int length = 0;
    string a = "yamada";
    string b = "taro";
    string c = "japan";

    for (int i = 0; i < _loopCount; i++)
    {
        string value = $"{a}.{b}.{c}";
        length += value.Length;
    }

    return length;
}


|        Method |     Mean |    Error |   StdDev |
|-------------- |---------:|---------:|---------:|
|   StringPlus4 | 17.24 ms | 0.134 ms | 0.119 ms |
|   StringPlus5 | 42.29 ms | 0.834 ms | 1.114 ms |
| DollarFormat4 | 17.27 ms | 0.327 ms | 0.350 ms |
| DollarFormat5 | 41.60 ms | 0.831 ms | 1.875 ms |

うん、5つ(a.b.c)の時は、4つの時(a.b.)よりすごく遅くなっていますね。
5つの時は、$””の方が少し速いらしい。
$””の方は、可動性とか考えると便利なので、速度だけではその真価は測れませんが・・・。

さて、何が起こっているか調べるのに、

https://sharplab.io/

を使用してみます。
環境を、Roslyn branches → main(25 Jun 2022)
Resultsを C# にします。

ソースにいろいろ書いて、解釈を確認しますと、

string value1 = a + "." + b + ".";
// ↓
string text5 = string.Concat(text, ".", text2, ".");

string value2 = $"{a}.{b}.";
// ↓
string text6 = string.Concat(text, ".", text2, ".");

string value3 = a + "." + b + "." + c;
// ↓
string[] array = new string[5];
array[0] = text;
array[1] = ".";
array[2] = text2;
array[3] = ".";
array[4] = text3;
string text7 = string.Concat(array);

string value4 = $"{a}.{b}.{c}";
// ↓
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(2, 3);
defaultInterpolatedStringHandler.AppendFormatted(text);
defaultInterpolatedStringHandler.AppendLiteral(".");
defaultInterpolatedStringHandler.AppendFormatted(text2);
defaultInterpolatedStringHandler.AppendLiteral(".");
defaultInterpolatedStringHandler.AppendFormatted(text3);
string text8 = defaultInterpolatedStringHandler.ToStringAndClear();

と解釈されている様です。

4つまでの単純なstringの結合は、+でも$””でもstring.Concatになってこれが最速。

5つからは、+で結合すると、string[]を作るので遅い。
$””の場合は、Stringhandlerを作るので、昔より速くても、そこそこ遅い。となってしまうようです。

投稿日:
カテゴリー: C#

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です