2

concat、StringBuffer、StringBuilderの違いを知っています。私は、メモリを爆発させる可能性のあるStringBuffer.toStringバッキング配列のメモリの問題を認識しています。私は、初期容量に2の累乗を割り当てることで構成されるJDKSunの最適化についても知っています。

しかし、StringBuffer(toString()で使用)を再利用するための最良の方法について、またはStringBufferの再利用が適切であるかどうかについてはまだ疑問に思っています。メモリと速度のパフォーマンスを念頭に置いて、どちらが優れていますか?

public String toString2() {
  StringBuffer sb = new StringBuffer(<size>) 
  ... several .append(stuff) ...
  sb.trimToSize()
  return sb.toString()
}

また

private StringBuffer sb = new StringBuffer(<size>) 
public String toString2() {
  sb.delete()
  sb.setLength(1024)
  sb.trimToSize() 
  ... several .append(stuff) ...
  return sb.toString()
}

なぜ ?

4

4 に答える 4

3

最初の例は間違いなく明確で、読みやすく、安全です。これは、ほとんどの場合、パフォーマンスのマイクロ最適化の懸念よりも優先されます。パフォーマンスの問題があり、それがこのコードの一部によって引き起こされていることを(具体的な測定で)証明でき、ローカル環境では2番目の例が大幅​​に高速であることを測定によって証明できる場合は-そしてその場合にのみ、それを使用する正当な理由があります。

そうでなければ、あなたの質問に対する一般的な答えはありません。2番目の例が平均でn %速いと人々が主張した場合、マシンに違いがない場合(環境が異なるため、または実際のコードがほとんど呼び出されないため)、どのように役立ちますか?あなたのアプリで)?

ただし、私の個人的な直感では、最新のJVM(少なくともJDK6では、おそらくすでにJDK5では)では、短命のオブジェクトの割り当て/割り当て解除を非常に巧妙なGCトリックで行うため、最初の例の方が実際には高速である可能性があります。安いです。特に、同期のオーバーヘッドがないのStringBuilder代わりにを使用した場合はそうです。StringBuffer

于 2012-04-16T09:02:06.920 に答える
2
  1. StringBuilder--の非同期バリアントであるを使用StringBufferします。これにより、すぐにパフォーマンスを向上させることができます。
  2. 呼び出す必要はありません。新しいchar配列を作成するようtrimToSizeに強制しているだけです。StringBuilder
  3. StringBuilderJVMは短命のオブジェクトの割り当て用に高度に最適化されているため、を再利用することでほとんど節約できません。
  4. StringBuilder文字列を単一の式で表現できない場合にのみ、単純な連結式の代わりに使用します。たとえば、いくつかのものを繰り返し処理している場合です。連結は、を使用して基本的に同じコードにコンパイルされますStringBuilder
于 2012-04-16T09:09:38.027 に答える
0

パフォーマンスが懸念される場合は、特にStringBufferを使用しません。

1つのスレッドだけがtoString()を呼び出すかどうか確信が持てない場合は、毎回StringBuilderを作成します。

あなたが持っている他の問題は、異なるデータ型が多くのゴミを作成するint可能double性があることです。

StringBuilderはリサイクルせず、単純に保つだけです。本当に最大のパフォーマンスが必要な場合は、ガベージを作成しないライブラリを備えた直接ByteBufferのような別のソリューションを使用します。

于 2012-04-16T09:04:05.493 に答える
0

両方のパフォーマンステストを試してください。パフォーマンスに関するすべての質問と同様に、コンテキストとメソッドの呼び出し方法によって異なります。

いくつかのメモ:

  • StringBuilderはスレッドセーフではありませんが、最初の例では、メソッドがフィールドを使用していないため、スレッドセーフは問題になりません。これにより、StringBuilderより高速になりStringBufferます。
  • 2番目のアプローチはスレッドセーフではないため、メソッドを呼び出す複数のスレッドがある場合、両方のスレッドがセーフを使用するためStringBuffer、両方の呼び出しからの要素を含む文字列になります。
  • 周りを維持する場合(2番目の例)、メソッドを使用する頻度によっては、ガベージコレクターが他のオブジェクトで使用される可能性StringBufferのあるによって使用されるメモリを収集しないため、実際にはより多くのメモリを保持している可能性があります。StringBuffer
于 2012-04-16T09:11:21.853 に答える