【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 は利用しない方が賢明です。