Javaで文字列結合をする際、String型で+=
で繋いでいくか、StringBuilderのappend()
でつなぐか、2通りの手段があります。
結果はどちらも同じですが、処理速度に差が出ます。
Stringでやったとき
例えばこんなコード
String stringResult = null; // Stringオブジェクトによる文字列結合 for (int i = 0; i < 10; i++) { String str = Integer.toString(i); stringResult += str; }
String型とはStringオブジェクトのことなので、String型の変数が宣言される=Stringオブジェクトが生まれる、ということになります。
なので、文字列結合をしているstringResult += str;
のタイミングでStringオブジェクトを生成しています。
つまり、for文のループの回数分だけStringオブジェクトが生まれるわけです。
StringBuilderでやったとき
例えばこんなコード
StringBuilder sb = new StringBuilder(); // StringBuilderによる文字列結合 for (int j = 0; j < 10; j++) { sb.append(Integer.toString(j)); }
結果はStringの例と同じです。
しかし、append()
はStringオブジェクトを作りません。末尾に追加していくだけです。
Stringオブジェクトを生成しない分、処理が速い。
どれくらい速度が違う?
下記のようなプログラムで、StringとStringBuilderとの処理時間の違いを測ってみました。
public class StringBuilderSample{ public static void main(String[] args) { final int MAX_COUNT = 100; System.out.println("結合回数:" + MAX_COUNT + "回のとき"); /********************* String型の場合 *********************/ String stringResult = null; // Stringでの処理にかかった時間 long sTime; // 開始時間 long startTime = System.nanoTime(); // String型による文字列結合 for (int i = 0; i < MAX_COUNT; i++) { String str = Integer.toString(i); stringResult += str; } // 終了時間 long endTime = System.nanoTime(); // 処理にかかった時間を算出 sTime = endTime - startTime; System.out.println("Stringでの処理時間:" + sTime + "ナノ秒"); /********************* StringBuilderの場合 *********************/ StringBuilder sb = new StringBuilder(); // StringBuilderでの処理にかかった時間 long sbTime; // 開始時間 startTime = System.nanoTime(); // StringBuilderによる文字列結合 for (int j = 0; j < MAX_COUNT; j++) { sb.append(Integer.toString(j)); } // 終了時間 endTime = System.nanoTime(); // 処理にかかった時間を算出 sbTime = endTime - startTime; System.out.println("StringBuilderでの処理時間:" + sbTime + "ナノ秒"); System.out.println("StringBuilderの方が " + (sTime - sbTime) + " ナノ秒速い"); } }
文字列結合をMAX_COUNT
の回数だけ行ったときの処理速度を表示するプログラムです。
以下、MAX_COUNT
の値を100, 1000, 1万, 10万と増やしていきながら処理時間の違いを見ていきます。
ちなみに、ナノ秒とは10 ^ (-9) 秒(=0.000000001秒)のことです。
100回実行したとき
1000回実行したとき
1万回実行したとき
約0.57秒速い
10万回実行したとき
約27秒速い
雑感
1000回ぐらいまでならせいぜいマイクロ秒(10 ^(-6))単位での違いなので、そんなに気にはならない。
1万回超えたあたりから処理時間の差が気になるレベルになってくる。
まあ何回実行するにしてもStringBuilderの方が速いことは確かなので、特別な理由がない限り文字列結合はStringBuilderでやったほうがいいですね。