3

String を返すゲッターがあり、それを他の String と比較しています。null の戻り値をチェックするので、ifステートメントは次のようになります (true の場合は実際に早期に終了します)。

if (someObject.getFoo() != null && someObject.getFoo().equals(someOtherString)) {
  return;
}

パフォーマンス的には、このように getter を 2 回呼び出すよりも、返された String を格納するほうがよいでしょうか? それも問題ですか?

String foo = someObject.getFoo();
if (foo != null && foo.equals(someOtherString)) {
  return;
}

コメントからの質問に答えるために、このチェックはあまり頻繁には実行されず、ゲッターはかなり単純です。私は、新しいローカル変数を割り当てることと、ゲッターを追加で実行することとを比較する方法に最も興味があります。

4

5 に答える 5

11

ゲッターが何をするかに完全に依存します。それが単純なゲッター (データ メンバーを取得する) である場合、コードがパフォーマンスのホット スポットであると判断された場合、JVM はオンザフライでインライン化できます。これが、Oracle/Sun の JVM が「HotSpot」と呼ばれる理由です。:-) 必要な場合 (可能な場合)、積極的な JIT 最適化を適用します。ただし、ゲッターが何か複雑なことを行う場合、当然、それを使用してその作業を繰り返すのが遅くなる可能性があります。

もちろん、コードがホット スポットでない場合は、パフォーマンスに違いがあるかどうかは気にしません。

インライン化されたゲッターは、ローカル変数にキャッシュされた値よりも高速になる場合があると誰かが言ったことがありますが、私はそれを自分自身で証明したことはなく、なぜそうなるのかの背後にある理論も知りません。

于 2013-01-23T17:51:45.033 に答える
4

2 番目のブロックを使用します。いずれにしても、最初のブロックは 2 番目のブロックに最適化される可能性が高く、2 番目の方が読みやすくなります。 ただし、主な理由は、 someObject が他のスレッドによってアクセスされた場合、および最適化が何らかの形で無効になった場合、最初のブロックが NullPointerException 例外の終了をスローしないことです。

また、マルチスレッドがなくても、万が一 someObject をvolatileにすると、最適化が消えてしまいます。(パフォーマンスが悪く、もちろん、複数のスレッドでは非常に悪いです。) そして最後に、2 番目のブロックはデバッガーの使用を容易にします (必ずしも必要ではありません)。

于 2013-01-23T19:12:15.730 に答える
1

equals がそれを行うため、最初の null チェックを省略できます。

引数が null ではなく、このオブジェクトと同じ文字シーケンスを表す String オブジェクトである場合にのみ、結果は true になります。

したがって、最善の解決策は次のとおりです。

if(someOtherString.equals(someObject.getFoo())
于 2013-01-23T22:31:10.487 に答える
0

私は 2 番目のコード ブロックを好みます。これは foo を割り当て、その後 foo を null/notnull に変更できないからです。

Null が必要になることが多く、Java は「Elvis」演算子を使用してこれを解決する必要があります。

if (someObject.getFoo()?.equals(someOtherString)) {
  return;
}
于 2013-01-24T06:34:09.080 に答える
0

パフォーマンスに関しても、どちらも同じように見えます。返された値をそれ以上使用しないことが確実な場合は、1 番目のブロックを使用し、そうでない場合は、2 番目のブロックを使用します。

于 2013-01-23T17:55:09.163 に答える