0

1つの要素を含むリストがありますが、後で追加される可能性があります。私が使用しているリストはArrayListです。forループを使用する代わりにList.get(0)を呼び出すと、より高速な結果が得られることがわかりました。どうしてこれなの?1つのアイテムをループすることは、1つのアイテムを取得することと同じではありませんか?そうでない場合、どうすれば同様のパフォーマンスを得ることができますか?私の配列は最終的に1つのアイテムよりも大きくなることを知っています。私はopenglレンダラーの本体でこのループを使用しています。ループを使用すると、fpsが45低下します。

編集:問題を修正しました。私のレンダラーは、レンダリングされるたびにリストに新しい値を追加していました。

4

4 に答える 4

3

Java で強化された for ループ (for-each) を使用すると、次のように動作するコンパイル済みコードが得られます。

Iterator<Thing> it = list.iterator();
while(it.hasNext()) {
  yourLoop.loopBody(it.next());
}

おそらくこれと同等であると予想していましたか?

for (int i = 0; i < list.size(); i++) {
  yourLoop.loopBody(list.get(i));
}

しかし、これは当てはまりません。反復子の構築には、観察している追加の時間がかかります。

于 2012-06-11T23:23:48.790 に答える
0

実装を知らなければList、特定の答えを実際に与えることはできません。たとえば、ArrayListは配列によってサポートされているため、呼び出しgetは基本的に配列アクセスです。

for一方、ループの「foreach」バー​​ジョンを使用するには、 Iterator. これが速度低下の原因と考えられます。Iterator一部の実装には、 orの複雑な実装がありListIteratorます。

その答えは、スタイルと読みやすさの問題です。ほとんどの Java プログラマーは、foreach ループの方がはるかに読みやすく、意図が明確であると言うでしょう。そして、List(例えばLinkedList)のいくつかの実装では、はるかに高速です。

于 2012-06-11T23:24:46.143 に答える
0

私はコレクションの専門家ではありませんが、特定のアイテムを単に取得するよりも反復を設定する方が費用がかかります。

foreach を設定すると、コレクション内にいくつの項目があるかがわからないため、リストに含まれる項目の数に関係なく反復用に設定されます。

于 2012-06-11T23:24:47.677 に答える
0

一般に、速度が心配な場合、ArrayList を使用していることがわかっている場合の最速の方法は次のとおりです。

int size = list.size();
for (int i=0;i<size;i++) {
  Thing thing = list.get(i);
}

「サイズ」メソッドのオーバーヘッドは最小限ですが、すべてのループで呼び出す必要がないのはオーバーヘッドです。ArrayList の get() メソッドは O(1) です。これにより、Iterator と同様のパフォーマンスが得られるはずです。ArrayList の反復子コードを見ると、それは非常に単純であり、唯一の実際の余分なオーバーヘッドは、オブジェクトの作成と同時変更チェックによるものです。

ただし、LinkedList の場合、このタイプのループは、LinkedList の .get() メソッドが O(n) であるため、ひどいパフォーマンスをもたらします。イテレータは、反復ごとにポインタのチェックと再割り当てを行うだけなので、はるかに高速です。 next() への呼び出しごとに O(1) になります。

于 2012-06-12T04:06:26.347 に答える