マイナー・マイナー

隠れた名作の発掘が生きがい。

String,StringBuffer,StringBuilderの実行時間を比較してみた


スポンサードリンク

Javaでは,文字列を管理するクラスとして,java.langパッケージに含まれる次の3つがあります.

(A) String
(B) StringBuffer
(C) StringBuilder

それらの大きな違いを次の表の通りです.

String StringBuffer StringBuilder
文字列変更可能
×
スレッドセーフ
×
×

スレッドセーフとはスレッドが安全に動作するかどうかであり,それを実現すると安全性が保証される代わりに実行速度は低下するようです.つまり,StringBufferはStringとStringBuilderよりも実行速度は遅くなりそうです.


その確認のために次のようなプログラムを作成して実行してみました.比較したのは3つのクラスに共通するlengthとreplaceです.

public class StringTest {

	public static void main(String[] args) {
		StringBuffer stringBuffer = new StringBuffer("a");
		StringBuilder stringBuilder = new StringBuilder("a");
		String string = "a";
		int loop = 10000000;
		long start;
		long stop;

		// Stringの実行時間計測
		start = System.currentTimeMillis();
		for (int i = 0; i < loop; i++) {
			string.length(); // (A-1)
			// string.replace("a", "a"); //(A-2)
		}
		stop = System.currentTimeMillis();
		System.out.println("Stringの実行時間:" + (stop - start));

		// StringBufferの実行時間計測
		start = System.currentTimeMillis();
		for (int i = 0; i < loop; i++) {
			stringBuffer.length(); // (B-1)
			// stringBuffer.replace(0, 1, "a"); //(B-2)
		}
		stop = System.currentTimeMillis();
		System.out.println("StringBufferの実行時間:" + (stop - start));

		// StringBuilderの実行時間計測
		start = System.currentTimeMillis();
		for (int i = 0; i < loop; i++) {
			stringBuilder.length(); // (C-1)
			// stringBuilder.replace(0, 1, "a"); //(C-2)
		}
		stop = System.currentTimeMillis();
		System.out.println("StringBuilderの実行時間:" + (stop - start));
	}
}


lengthメソッドの実行結果(上記ソースをそのまま実行)


Stringの実行時間:34
StringBufferの実行時間:442
StringBuilderの実行時間:18

StringBuilderはJDK5.0で追加されたクラスであると書いてあったため,StringBuilderはStringクラスを拡張したクラスであり,実行速度はStringよりも劣ると思っていました.しかし,実際にはStringBuilderの方が実行速度は速いという結果になりました.


replaceメソッドの実行(上記ソースの(*-1)をコメントアウトし,(*-2)のコメントアウトを外して実行)


Stringの実行時間:15060
StringBufferの実行時間:847
StringBuilderの実行時間:390

Stringの実行時間は多いです.replaceは”String”と”StringBuffer,StringBuilder”とで引数指定がが違うため,アルゴリズムも大きく違うものだと想像します.

もしかしたらStringの実行後,StringBufferやStringBuilderを実行すると,共通のメモリ領域で使える部分を再利用しているため速くなっているのだと想像し,例えばStringBufferのメソッド実行時はStringとStringBuilderのメソッドをコメントアウトするなどして一つ一つの実行時間も調べました.結果は,実行時間は変わるものの,各メソッドの実行時間の大小関係は上記の結果通りでした.


うーん,どうやら各クラスはメソッドごとに実行時間の一長一短がありそうです.