5

私はちょうど興味があります: この 2 つのループの実装の間で速度とパフォーマンスに違いはありますか? size ()メソッドが、要素のグループを処理する配列、コレクション、またはオブジェクトの長さを返すと仮定します (実際にはXOM API からのものです)。

実装 1:

int size = someArray.size();
for (int i = 0; i < size; i++) {
    // do stuff here
}

実装 2:

for (int i = 0; i < someArray.size(); i++) {
    // do stuff here
}
4

6 に答える 6

4

パフォーマンスの観点からは、ほとんど違いはありません。これは、 size() ルックアップがインライン化されるようにループを最適化できるため、パフォーマンスの違いがほとんどないためです。

主な違いは、ループ中にサイズが変化するかどうかです。最初のケースでは、固定回数反復しようとします。2 番目のケースでは、反復回数は最終的な size() によって異なります。

于 2011-02-26T10:41:11.290 に答える
1

はい、違いがあります。最初のループでは、 size() メソッドが 1 回だけ呼び出されます。2 番目のものでは、反復ごとに呼び出されます。

反復によってコレクションのサイズが変更される場合 (これは非常にまれです)、2 番目のコレクションが必要になります。ほとんどの場合、最初のものを優先する必要がありますが、サイズ変数のスコープを制限します。

for (int i = 0, size = someArray.size(); i < size; i++) {
    // ...
}

しかし、ほとんどの場合、とにかく foreach 構文を優先する必要があります。

for (Foo foo : collection) {
    // ...
}

たとえば、インデックス付きアクセスが最適ではない LinkedList の場合でも、配列またはコレクションを効率的に反復処理します。

于 2011-02-26T10:32:53.737 に答える
1

心配しないでください。最近の JVM 最適化は非常に積極的です。

2 番目の形式を使用すると、より読みやすく、おそらく同じくらい高速になります。時期尚早の最適化ヤダヤダ。

そして、速度を改善する必要がある場合は、常に最初にプロファイルを作成し、推測しないでください。

size() をローカル変数にキャッシュすることがアプリに大きなメリットをもたらす可能性はほとんどありません。その場合、巨大なデータセットに対して単純な操作を行っているに違いありません。その場合、ArrayList をまったく使用しないでください。

于 2011-02-26T11:51:19.203 に答える
1

最初のスニペットは 1size()回しか呼び出されないため、より高速に実行されるはずです。2 番目のスニペットはsize()N 回呼び出します。実装に応じて。特に重大なペナルティをもたらす可能性があります。コンパイラがメソッドをインライン化するのが難しいと判断した場合、および/またはsize()メソッドが不揮発性変数を返すだけではない場合など。

私はそれを次のように書き直したでしょうfor(int i=0, s=someCollection.size(); i<s; i++)

注: 配列にはメソッドがありませんsize()

于 2011-02-26T10:28:43.990 に答える
0

たぶん、この構造に注意する価値があります:

for (String s : getStringsList()) {
    //...
}

一度だけ呼び出しgetStringsList()て、裏でイテレータを操作します。そのため、時間のかかる操作を実行したり、内部の状態を変更したりしても安全getStringsList()です。

于 2011-02-26T12:45:38.673 に答える
0

メソッドの呼び出し、変数への値の割り当て、条件のテストなど、ループの外で実行できることは常に避けてください。

メソッド呼び出しは、呼び出しのない同等のコードよりもコストがかかります。また、メソッド呼び出しを何度も繰り返すことで、アプリケーションにオーバーヘッドが追加されるだけです。

コードの書き直しが必要な場合でも、すべてのメソッド呼び出しをループの外に移動します。

利点 :-

コンパイラが最適化しない限り、ループ条件はループの反復ごとに計算されます。

条件値が変更されない場合は、メソッド呼び出しがループの外に移動すると、コードの実行が速くなります。

ノート :-

メソッドがループ中に変更されない値を返す場合は、その値をループの前に一時変数に格納します。

したがって、その値はループ外の一時変数 size に格納され、ループ終了条件として使用されます。

于 2015-04-06T05:46:00.447 に答える