JavaのStringオブジェクトは次のような"+"演算子で結合することができます。
JDKに含まれているjavapというツールでクラスを逆アセンブルすることによって、Javaのソースがどのようにバイトコードに翻訳されているのかを見ることができます。Javaのコンパイラは、ソースが書かれた通りにコンパイルするのではなく、ある程度の最適化をするそうなので、上のコードが実際にどのようなバイトコードになっているのかを見てみました。次のようなプログラムを書いて、
StringBuilderを使って次のように書いた場合は
String str = "aaa" + "bbb";
私は長いSQL文を組み立てるときにこのような文字列の足し算を多用するのですが、どこかで「Stringの足し算は遅いのでStringBuffer(またはStringBuilder)を使うべき」と聞いたことがあったので、それが気になっていました。JDKに含まれているjavapというツールでクラスを逆アセンブルすることによって、Javaのソースがどのようにバイトコードに翻訳されているのかを見ることができます。Javaのコンパイラは、ソースが書かれた通りにコンパイルするのではなく、ある程度の最適化をするそうなので、上のコードが実際にどのようなバイトコードになっているのかを見てみました。次のようなプログラムを書いて、
public class StringTest{
public static void main(String[] args){
String str = "aaa"+"bbb"+"ccc";
System.out.println(str);
}
}
コンパイルします。public static void main(String[] args){
String str = "aaa"+"bbb"+"ccc";
System.out.println(str);
}
}
>javac StringTest.java
生成されたStringTestクラスの内容をjavapで表示します。逆アセンブルする場合は -c オプションを使います。>javap -c StringTest
StringTestクラスのバイトコードが次のように表示されます。Compiled from "StringTest.java"
public class StringTest extends java.lang.Object{
public StringTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String aaabbbccc
2: astore_1
3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_1
7: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
}
これを見る限り String str = "aaa"+"bbb"+"ccc"; がコンパイルされるとpublic class StringTest extends java.lang.Object{
public StringTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String aaabbbccc
2: astore_1
3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_1
7: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
}
0: ldc #2; //String aaabbbccc
になるようです。StringBuilderを使って次のように書いた場合は
public class StringTest2{
public static void main(String[] args){
StringBuilder sb = new StringBuilder();
sb.append("aaa").append("bbb").append("ccc");
System.out.println(sb.toString());
}
}
こんなバイトコードになります。public static void main(String[] args){
StringBuilder sb = new StringBuilder();
sb.append("aaa").append("bbb").append("ccc");
System.out.println(sb.toString());
}
}
Compiled from "StringTest2.java"
public class StringTest2 extends java.lang.Object{
public StringTest2();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: astore_1
8: aload_1
9: ldc #4; //String aaa
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6; //String bbb
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7; //String ccc
21: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: pop
25: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
28: aload_1
29: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
32: invokevirtual #10; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
35: return
}
単純なStringの足し算の場合はStringBuilderを使うより速そうですね。public class StringTest2 extends java.lang.Object{
public StringTest2();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: astore_1
8: aload_1
9: ldc #4; //String aaa
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6; //String bbb
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7; //String ccc
21: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: pop
25: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
28: aload_1
29: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
32: invokevirtual #10; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
35: return
}
投稿:竹形 誠司[takegata]/2009年 02月 22日 13時 14分
/更新:2009年 02月 22日 13時 15分