読者です 読者をやめる 読者になる 読者になる

文字列の連結の速度比較: string.Join vs StringBuilder

文字列の連結の速度比較をしてみました。

  • List<string> クラスに文字列を格納し、string.Join() で文字列を連結する。
  • StringBuilder クラスに文字列を格納し、ToString() メソッドで文字列を生成する。

上記 2 通りの方法で速度を計測してみました。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

class Program {
    static void Test(int n, string s) {
        // List<string> と string.Join() の組み合わせによる文字列の連結
        var sw1 = new Stopwatch();
        sw1.Start();
        var xs = new List<string>();
        for (int i = 0; i < n; i++) {
            xs.Add(s);
        }
        string s1 = string.Join("", xs);
        sw1.Stop();

        // StringBuilder による文字列の連結
        var sw2 = new Stopwatch();
        sw2.Start();
        var buf = new StringBuilder();
        for (int i = 0; i < n; i++) {
            buf.Append(s);
        }
        string s2 = buf.ToString();
        sw2.Stop();

        // 確認のため、長さ比較
        if (s1.Length != s2.Length) throw new Exception();

        Console.WriteLine("文字列の長さ : {0:N0}", s1.Length);
        Console.WriteLine("string.Join  : {0,4}ms", sw1.ElapsedMilliseconds);
        Console.WriteLine("StringBuilder: {0,4}ms", sw2.ElapsedMilliseconds);
        Console.WriteLine();
    }

    static void Main() {
        var cs = new List<string>();
        for (int i = 0; i < 10; i++) {
            cs.Add("0123456789");
        }
        string s = string.Join("", cs); // 長さ 100 の文字列

        Test(10000, s);
        Test(100000, s);
        Test(1000000, s);
    }
}

実行結果です。

文字列の長さ : 1,000,000
string.Join  :    2ms
StringBuilder:    2ms

文字列の長さ : 10,000,000
string.Join  :   25ms
StringBuilder:   22ms

文字列の長さ : 100,000,000
string.Join  :  275ms
StringBuilder:  253ms

速度差はほぼないようですね。単純な文字列の連結ならば、いずれの方法でも問題なさそうです。

環境

  • OS X El Capitan 10.11.1
  • Mono JIT compiler version 4.2.0