C#の文字列連結(+, string.Join, StringBuilder)
最近C#の文字列連結を適当に書いてやらかしちゃったので反省のためにまとめる
検証環境はC# .Net Core 3.1
やらかしたコード
var outText = ""; foreach(var i in Enumerable.Range(1, N)) { outText += i.ToString() + " "; }
リストの中身を文字列に変換して+=でどんどん連結していくコード
連結の回数が少なければ問題ないけどループ回数が増えると遅すぎて話にならない
N | ループにかかる時間 |
---|---|
1 | 0 ms |
10 | 0 ms |
100 | 0 ms |
1000 | 2 ms |
10000 | 67 ms |
100000 | 15553 ms |
対策
string.Joinを使う
配列を文字列で連結するときはstring.Joinが正解
上記のコードを書き直すとこんな感じ
これなら1000万データぐらいまでは大丈夫そう
var list = Enumerable.Range(1, N); var outText = string.Join(" ", list);
N | ループにかかる時間 |
---|---|
1 | 0 ms |
10 | 0 ms |
100 | 0 ms |
1000 | 0 ms |
10000 | 1 ms |
100000 | 10 ms |
1000000 | 78 ms |
10000000 | 1040 ms |
100000000 | 9260 ms |
StringBuilderを使う
配列じゃないときは大体StringBuilderが正解
コードはこんな感じ
foreach (var i in Enumerable.Range(1, N)) { sb.Append(i).Append(" "); } outText = sb.ToString();
N | ループにかかる時間 |
---|---|
1 | 0 ms |
10 | 0 ms |
100 | 0 ms |
1000 | 0 ms |
10000 | 0 ms |
100000 | 6 ms |
1000000 | 60 ms |
10000000 | 730 ms |
100000000 | 7061 ms |
まとめ
N | += | string.Join | StringBuilder |
---|---|---|---|
1 | 0 ms | 0 ms | 0 ms |
10 | 0 ms | 0 ms | 0 ms |
100 | 0 ms | 0 ms | 0 ms |
1000 | 2 ms | 0 ms | 0 ms |
10000 | 67 ms | 1 ms | 0 ms |
100000 | 15553 ms | 10 ms | 6 ms |
1000000 | ---- | 78 ms | 60 ms |
10000000 | ---- | 1040 ms | 730 ms |
100000000 | ---- | 9260 ms | 7061 ms |
どうやらStringBuilderのほうが若干早いっぽい
とにかくループで文字列連結するときは+=はやめよう