文字列結合の+演算子(2)

文字列結合の+演算子(1)のつづきです。


会社で識者の方にいろいろ話を聞いてみたところ、javacによる+演算子最適化の真骨頂は、リテラルの自動結合なんだそうです (下記参照)。逆に言えば、リテラルでない要素が含まれている場合は、あんまり嬉しくない状況になることもままあるようです。というのは、いくらString(Buffer|Builder)への変換が行われるとは言っても、この方々の持つ内部バッファであるchar配列の初期サイズはたったの16 (Sunの実装の場合) でしかありません。加算される要素の数と大きさ次第では、それこそ何度も何度も何度も何度も……配列確保 & 要素コピーが走ってしまうこともあり得るようです。おならぷー。
こういう時はやはり、コンストラクタで初期長を指定した上でString(Buffer|Builder)を手動で操作する方が良いようです。

javaコード

import java.util.*;

public class test
{
	public static void main(String[] args)
	{
		String a = "aaa"
		+ "bbbb"
		+ 9999
		+ "cccc"
		+ 0xFFFF
		+ "dddd";

		System.out.println( a );
	}
}

コンパイル結果

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: annotate fullnames lnc 
// Source File Name:   test.java

import java.io.PrintStream;

public class test
{

            public test()
            {
/*   3*/    //    0    0:aload_0         
/*   3*/    //    1    1:invokespecial   #1   <Method void Object()>
/*   3*/    //    2    4:return          
            }

            public static void main(java.lang.String args[])
            {
/*   7*/        java.lang.String s = "aaabbbb9999cccc65535dddd";
/*   7*/    //    0    0:ldc1            #2   <String "aaabbbb9999cccc65535dddd">
/*   7*/    //    1    2:astore_1        
/*  14*/        java.lang.System.out.println(s);
/*  14*/    //    2    3:getstatic       #3   <Field java.io.PrintStream java.lang.System.out>
/*  14*/    //    3    6:aload_1         
/*  14*/    //    4    7:invokevirtual   #4   <Method void java.io.PrintStream.println(java.lang.String)>
/*  15*/    //    5   10:return          
            }
}