The King's Museum

ソフトウェアエンジニアのブログ。

【Effective Java】項目51:文字列結合のパフォーマンスに用心する

文字列の結合演算子(+)は文字列を結合するための便利な演算です。 しかし、これを利用する場合にはパフォーマンスに注意する必要があります。

Java の文字列(String)は不変です。 そのため、2つの文字列が連結される時、2つの文字列をコピーして連結した新しい文字列が生成されます。

例えば次のプログラムは、実行するとかなり悪いパフォーマンスとなります。

public String statement() {
    String result = "";
    for (int i = 0; i < numItems(); i++) {
        result += lineForItem(i);
    }
    return result;
}

このメソッド中段の文字列結合では、繰り返し毎に新しいインスタンスが生成されます。 さらに、毎回、文字列の長さの分のコピー操作が発生してしまいます。

StringBuilder

文字列の連結によるパフォーマンス劣化を防ぐためには String の代わりに StringBuilder を使用します。

public String statement() {
    StringBuilder b = new StringBuilder(numItems() * LINE_WIDTH);
    for (int i = 0; i < numItems(); i++) {
        b.append(lineForItem(i));
    }
    return b.toString();
}

StringBuilder を使うとパフォーマンスの違いは顕著となります。

String を利用した場合、繰り返し毎に新しいインスタンスの生成とコピー操作が発生するのに対し、 StringBuilder を利用した場合はそのような操作は行われません。

通常、StringBuilder では最初に文字列のサイズを与えておくべきですが、たとえサイズを最初に与えなくても String のパフォーマンスよりはだいぶましです。

StringBuffer

StringBuilder と同様の機能を持つクラスとして StringBuffer が存在します。

StringBuffer は StringBuilder の機能に加えて同期化機構を持っています。

一般的に StringBuffer が使われる場所での同期化機構は必要ないはずです。 そのため StringBuffer は利用しない方が賢明です。

(c) The King's Museum