私は(Better、Faster、Lighter Java)(Bruce TateとJustin Gehtlandによる)を読んでいて、アジャイルタイプチームの読みやすさの要件に精通しています。ロバート・マーティンが彼のきれいなコーディングの本で話しているようなものです。現在のチームでは、実行時に余分な(そして不要な)文字列オブジェクトを作成するため、_+
_演算子を使用しないように明示的に指示されています。
しかし、これは article です。'04年に書き戻されたのは、オブジェクト割り当てが約10の機械語命令である方法についてです。 (基本的に無料)
また、GCがこの環境でのコスト削減にどのように役立つかについても説明します。
_+
_、StringBuilder
、またはStringBuffer
の使用間の実際のパフォーマンストレードオフは何ですか? (私の場合、Java 1.4.2に制限されているため、StringBuffer
のみです。)
StringBuffer
を使用すると、Tateの本にあるいくつかの例が示すように、コードが見にくく、読みにくくなります。そして、StringBuffer
はスレッド同期されます。これは、_+
_演算子の使用における「危険」を上回る独自のコストがあるようです。
考え/意見?
String
連結の使用は、コンパイラーによってStringBuilder
操作に変換されます。
コンパイラーの動作を確認するには、サンプルクラスを使用して、それをコンパイルし、jadで逆コンパイルして、生成されたバイトコードを確認します。
元のクラス:
public void method1() {
System.out.println("The answer is: " + 42);
}
public void method2(int value) {
System.out.println("The answer is: " + value);
}
public void method3(int value) {
String a = "The answer is: " + value;
System.out.println(a + " what is the question ?");
}
逆コンパイルされたクラス:
public void method1()
{
System.out.println("The answer is: 42");
}
public void method2(int value)
{
System.out.println((new StringBuilder("The answer is: ")).append(value).toString());
}
public void method3(int value)
{
String a = (new StringBuilder("The answer is: ")).append(value).toString();
System.out.println((new StringBuilder(String.valueOf(a))).append(" what is the question ?").toString());
}
method1
コンパイラはコンパイル時に操作を実行しました。method2
String
連結は、手動でStringBuilder
を使用するのと同じです。method3
String
連結は、コンパイラが前のものを再利用するのではなく、2番目のStringBuilder
を作成しているため、明らかに悪いです。したがって、私の単純なルールは、たとえばループで、または中間結果を格納する必要がある場合など、結果を再度連結する必要がない限り、連結は適切であることです。
チームは 繰り返し文字列連結を回避する理由 について学ぶ必要があります。
StringBuffer
を使用することが理にかなっている場合areは確かにあります-特にループで文字列を作成している場合は特にループの反復回数が少ないことはわかりません。新しいオブジェクトを作成するだけの問題ではないことに注意してください。既に追加したすべてのテキストデータをコピーするだけです。また、ガベージコレクションを考慮しない場合、オブジェクトの割り当ては「本質的に無料」であることに注意してください。はい、現在の世代に十分なスペースがある場合、それは基本的にポインターをインクリメントすることの問題です...しかし:
これらのすべてはかなり安く、オブジェクトの作成を避けるためにエレガンスから離れてデザインを曲げる価値はありません...しかし、あなたはすべきではありませんfreeと見なします。
一方、中間の文字列が必要ない場合は、StringBuffer
を使用しても意味がありません。例えば:
String x = a + b + c + d;
少なくとも以下と同じくらい効率的です:
StringBuffer buffer = new StringBuffer();
buffer.append(a);
buffer.append(b);
buffer.append(c);
buffer.append(d);
String x = buffer.toString();
小さな連結の場合、読みやすくするために文字列と+を使用できます。パフォーマンスが低下することはありません。ただし、多数の連結操作を行う場合は、StringBufferを使用します。