9

より経験豊富な開発者に、1 つの単純なことについて尋ねたいと思いますが、私には明らかではありません。次のようなコード (Java) があるとします。

for(int i=0; i<vector.size(); i++){
   //make some stuff here
}

私はそのような声明に頻繁に出くわしたので、おそらく何も悪いことではありません. しかし、私にとっては、各反復で size メソッドを呼び出す必要はないようです。私はそのようなアプローチを使用します:

int vectorSize = vector.size();
for(int i=0; i<vectorSize; i++){
    //make some stuff here
}

ここで同じこと:

for(int i=0; i<myTreeNode.getChildren().size(); i++){
   //make some stuff here
}

私はまだプログラミングの専門家ではないので、私の質問は次のとおりです。生け垣全体のギャップを探しているのでしょうか、それともプロのコードでそのような詳細を処理することが重要ですか?

4

3 に答える 3

8

メソッド呼び出しでは、JVM が実際に追加処理を行う必要があります。あなたがしていることは、一見すると最適化のように見えます。

ただし、一部の JVM 実装は、メソッド呼び出しをインライン化するのに十分スマートであり、それらの場合、違いは存在しません。

たとえば、Android プログラミング ガイドラインでは、指摘されたことを実行することを常に推奨していますが、JVM 実装マニュアル (手に入れることができる場合) には、コードが最適化されるかどうかが示されます。

于 2013-04-25T19:02:51.053 に答える
2

通常size()、小さな一定時間の操作であるため、呼び出しsizeのコストはループ本体の実行のコストと比較して取るに足らないものであり、ジャスト イン タイム コンパイラがこの最適化を処理している可能性があります。したがって、この最適化にはあまりメリットがない場合があります。

とはいえ、この最適化はコードの可読性に悪影響を与えるものではないため、避けるべきものではありません。多くの場合、小さな要因によって速度に影響を与えるだけのコード最適化 (たとえば、O(n) 操作を O(1) 操作に変更する最適化とは対照的に) は、この理由で避ける必要があります。たとえば、ループを展開できます。

int i;
int vectorSizeDivisibleBy4 = vectorSize - vectorSize % 4; // returns lowest multiple of four in vectorSize
for(i = 0; i < vectorSizeDivisibleBy4; i += 4) {
    // loop body executed on [i]
    // second copy of loop body executed on [i+1]
    // third copy of loop body executed on [i+2]
    // fourth copy of loop body executed on [i+3]
}
for(; i < vectorSize; i++) { // in case vectorSize wasn't a factor of four
    // loop body
}

ループを 4 回アンロールすると、評価される回数が 4 分の 1 に減りますがi < vectorSize、その代償として、コードが読みにくくなります (命令キャッシュが台無しになり、パフォーマンスが低下する可能性もあります)。これをしないでください。しかし、私が言ったように、int vectorSize = vector.size()このカテゴリには当てはまらないので、試してみてください.

于 2013-04-25T19:07:29.540 に答える