2

次の 2 つのスニペットのどちらがlistArrayList であると仮定すると、どちらが高速か。

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

また

int count = list.size();
for(int i=0; i<count;i++){...}

また、最適化 (ある場合) は Android の ArrayAdapter に適用されますか?

int sCount = mAdapter.getCount();

明確化

forループでは、コンパイラーがlist.size()毎回呼び出すか、一度呼び出して後で使用しますか。

を呼び出すたびに、list.size()実際に項目がカウントされることに注意してください。それが質問の本質です。

4

6 に答える 6

3

ほとんどの場合、速度は区別できません。つまり、ループの実行中にコレクションが変更される可能性がある場合、2 つのループは意味的に異なります。コレクションの変更は、ループ内 (またはループ内で呼び出されるコード内) または同時に実行されている別のスレッド内で行われる可能性があります。

「明確化」に具体的に答えるには:はい、sizeメソッドはループを介して毎回呼び出されます。

このループの「最適化された」バージョンは、最適化が重要である (そしてコレクションが変更されていない) という明確な証拠がない限り、決して書きません。コードが非常に調整されていて、そのような微調整によって測定可能な速度が向上している場合は、かなり満足するはずです。

于 2013-09-23T20:53:10.640 に答える
2

いくつかの質問を自問する必要があります。

  • パフォーマンスに問題がありますか?
  • このコードのボトルネックをプロファイリングしましたか?

ブースの質問に「はい」と答えられる場合は、両方の方法を試して結果をプロファイルします。

実際、それだけでは変わらないと思います。

于 2013-09-23T20:49:51.503 に答える
0

2 番目のコードの方が少し速いと思います。メソッド呼び出しでは、コードをメモリにロードする必要があり、(最初のコードのように) メソッド メモリ スタックとの間でデータをロードします。これは明らかに、単一のメモリ アクセス (コードの最初の部分) よりも低速です。ただし、ループの反復中に配列のサイズが変わる可能性がある場合は、最初のコードを使用する方が安全だと思います。次の例を検討してください。

for(int i=0; i<list.size();i++){
  if list.get(i) == 0 { list.remove(i); i--; }
}    

上記の例では、配列から null 要素を削除しています。したがって、配列のサイズは要素が削除されるたびに減少します。list.size() を使用せず、配列のサイズを適切に更新するのを忘れると、「インデックスが範囲外」の例外が発生します。

于 2014-04-28T16:22:40.320 に答える
0
int count = list.size();
for(int i=0; i<count;i++){...}// Is faster
于 2013-09-23T20:49:21.103 に答える
0

適切なコンパイラは、これらをまったく同じアセンブリ コードにコンパイルします。

于 2013-09-23T20:48:08.387 に答える