竹形誠司 ブログ
Java+MySQL+Tomcat    »トピック一覧
掲示板へのスパムが多いため、「ご質問」のコーナーはユーザー登録制とさせていただきました。お手数ですが、上の「新規ユーザーの登録」メニューより登録をお願いします。
帳票Web
アプリケーション

受注開発始めました
詳しくは こちら
竹形 誠司 著/ラトルズ刊
JSP帳票アプリケーション実践開発入門
JSP帳票アプリケーション
実践開発入門

JSP業務アプリケーション短期開発入門
JSP業務アプリケーション
短期開発入門

Java+MySQL+Tomcatで始めるWebアプリケーション構築入門
Java+MySQL+Tomcatで始めるWebアプリケーション構築入門

Java+MySQL+Tomcatで作る掲示板とブログ
Java+MySQL+Tomcatで作る
掲示板とブログ
Stringの足し算は遅い?
by 竹形 誠司[takegata]
JavaのStringオブジェクトは次のような"+"演算子で結合することができます。
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);
    }
}
コンパイルします。
>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"; がコンパイルされると
  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());
    }
}
こんなバイトコードになります。
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を使うより速そうですね。

投稿:竹形 誠司[takegata]/2009年 02月 22日 13時 14分 /更新:2009年 02月 22日 13時 15分