StringBufferにおけるパフォーマンスチューニングの落とし穴

文字列を連結させる場合にStringBufferを使え(最近はStringBuilderか)というのが定石だがじつは落とし穴がある。


下記ソースではいずれも文字列を連結する処理なんだけども、”+”を使用するのが一番速い処理となってしまっている。


ちなみにコンパイラの最適化では1.が3.に置き換えられると思ってた。
※最適化では1.が4.になってた。(Java6で確認)ってことで1.はスレッドセーフではなくなってる。

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		
		String buf = "";
		for (int i = 0; i < 10000; i++) {
			//1. buf = buf + "aaa" + "bbb"; //2150ms. 2124ms. 2128ms.

			//2. buf = new StringBuffer(buf)
			//.append("aaa").append("bbb").toString(); //2155ms. 2144ms. 2150ms.
			
			//3. buf = new StringBuffer().append(buf)
			//.append("aaa").append("bbb").toString(); //4574ms. 4607ms. 4640ms.

	        //4. buf = new StringBuilder(buf)
			//.append("aaa").append("bbb").toString(); //2130ms. 2194ms. 2180ms.

		}
		long end = System.currentTimeMillis();
		
		System.out.println(end - start + "ms.");

	}

このように書くのが一番速い。(StringBuilderでも誤差1ms.程度)

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		
		String buf = "";
		StringBuffer b =  new StringBuffer(buf);
		for (int i = 0; i < 10000; i++) {
			b.append("aaa").append("bbb"); //6ms. 4ms. 5ms.
			
		}
		buf = b.toString();
		
		long end = System.currentTimeMillis();
		
		System.out.println(end - start + "ms.");

	}