`C#` で高速な文字列連結方法は…? / `null` を文字列結合する場合のメモ

C# で文字列連結時の速度について。

高速な文字列連結は…?

  • ループ内で文字列を大量に結合する場合などは StringBuilder が高速
  • +=String#Concat で処理されるため並べると遅い。
  • String#Concat で一度だけ文字列を結合する場合は StringBuilder よりも高速(a + b + c のような部分は Concat により結合されるので StringBuilder よりも高速)
  • ビルド時に結合可能な文字列はコンパイル時に結合されるので最高速(例えば @"a" + @"b" + @"c" はビルド時に @"abc" に結合される)
  • String.JoinString.Concat よりほんのすこしだけ遅いくらいでほぼ同じ
  • String.Format は早くないけど、可読性は高め。

そういうことで、場合によって使い分けましょう。 基本的には + 演算子や String.Format で問題ないだろうけど、 文字列を断続的に結合していく場合にはコストが大きい(Stringインスタンス大量生成 & ガベージコレクション)ので StringBuilder を使う。

string dummy = null;

System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

// StringBuilder で同様の操作
StringBuilder builder = new StringBuilder(20);
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 1000 * 1000; i++)
{
  for (int j = 0; j < 20; j++)
  {
    builder.Append("*");
    dummy = builder.ToString();
  }
  builder.Length = 0;
}

stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);

// + で結合する場合 - 上記の StringBuilder よりも高速
builder.Length = 0;
string a = builder.Append("*").ToString();
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 1000 * 1000; i++)
{
  // 20個連結
  dummy = a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a;
}

stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);

null の 文字列結合とか出力

下記コードで NullReferenceExceptionNullArgumentException は投げられない

string nullString = null;
Object nullObject = null;
Console.WriteLine(nullString);
Console.WriteLine(nullObject);
Console.WriteLine(nullString + "A" + nullObject);
Console.WriteLine(nullObject + "B" + nullString);
Console.WriteLine(string.Concat(nullString, nullObject));
Console.WriteLine(string.Format("{0}{1}", nullString, nullObject));

new StringBuilder().Append(nullString);

nullnull+= で足すと空文字になる

string str = null;
str += null;
Debug.Write(string.Empty.Equals(str)); // True

なんとも直感的では無いけど、 nullString += nullnull ではなく 空文字 になる

Share
関連記事