2012-03-09 2 views
1

を使用した場合Differrent二つの方法の間、あなたは文字列を逆にする、でしょうが二つの方法:のJava:たとえば新しいオブジェクト

最初:

String a = "StackOverFlow"; 
a = new StringBuffer(a).reverse().toString(); 

と第二は、次のとおりです。

String a = "StackOverFlow"; 
StringBuffer b = new StringBuffer(a); 
a = b.reverse().toString(); 

1)最初のコードでは、「ダミーオブジェクト」を作成しますStringBufferをメモリに保存してからreverseに変更し、Stringに変更してください。これは、GCがより有効に機能させるため、上記のコードで

2)は、第一以上の第二のより最適化するのですか?

感謝:)

+0

問題があることがわかっていない限り、コードの明瞭さはパフォーマンスよりも重要です。 –

答えて

1
  1. 最初の方法は、StringBufferの「ダミーオブジェクト」ではありません。
  2. あなたのコードの最後の行の下bへの他の参照がある場合を除き、オプティマイザは、すぐにそれがtoString

ていないがあることを行うのように、環境ガベージコレクトbを聞かせするのに十分な情報を持っていますbの変数は、newで作成されたオブジェクトを実際より少なくしません。コンパイラは両方のスニペットを同じバイトコードに最適化するでしょう。

1

StringBuffer bがダミーオブジェクトではありませんが(これは私がお願いしたい主な質問です)、参照です。スタックに常駐するポインタは基本的に単なるポインタであり、メモリ単位では非常に小さい。したがって、パフォーマンスに大きな差はないだけでなく(GCはこの例とは関係ありません)、Javaコンパイラはおそらくそれを完全に削除します(コードの他の場所で使用されていない場合)。

5

両方のスニペットで同じ数のオブジェクトが作成されます。唯一の違いは、ローカル変数の数です。これはおそらくスタックにある値の数を変更することさえありません.2番目のバージョンの場合、スタックスロットの1つに名前があります(b)。

オブジェクトの間で変数を区別することは非常に重要です。マイクロ最適化を試みるのではなく、まず読みやすいコードを書くことも重要です。明確で実用的なコードを取得したら、要件を満たすのに十分速いかどうかを測定する必要があります。そうでない場合は、最も効果的に変更を行い、その部分を最適化し、再測定などを行うためにプロファイルする必要があります。

0

最初の質問に答えると、JavaはStringBufferオブジェクトを作成します。それはあなたがそれがそうすると思うようにほとんど機能します。

あなたの2番目の質問に、私はJavaコンパイラがあなたのために世話をするだろうと確信しています。コンパイラにはフォルトがないわけではありませんが、このような簡単な例では、バイトコードを最適化すると思います。

ちょっとしたヒントですが、Javaの文字列は不変です。つまり、変更することはできません。したがって、新しい値を文字列に代入すると、Javaはメモリを切り出し、新しい文字列の値をその中に置き、変数を新しいメモリ空間にリダイレクトします。その後、ガベージコレクタが来て、古い文字列をクリアする必要があります。

関連する問題