2012-04-18 34 views
18

私の質問は、Androidコンパイラを使ったjavaの最適化に関するものです。以下のmap.values()は繰り返しごとに呼び出されるか、Androidコンパイラはそれを最適化します。foreachのforループとforループfor java

LinkedHashMap<String, Object> map; 

for (Object object : map.values()) 
{ 
    //do something with object 
} 

同様に、別の例があります。 aList.size()は繰り返しごとに呼び出されますか?

List<Object> aList; 

for (int i = 0; i < aList.size(); i++) 
{ 
    object = aList.get(i); 
    //do something with i 
} 

これ以降、すべての反復処理でメソッドを呼び出すかどうかは重要ですか? Map.values()、およびList.size()は何かをしますか?

+1

これは実際にAndroidとは特に関係のないJavaの質問です。 –

+0

私はこの質問に興味があることを理解していますが、現実的な目的のためには、コードを最適化する前にプロファイルを作成することを強くお勧めします。 –

+0

@PhilippReichart - あるコーディングスタイルが他のコーディングスタイルよりも優れたパフォーマンス上の優位性を持っているかどうかを尋ねるのは理にかなっています。また、プロファイリングにも限界があります。 Androidをコーディングする場合、コードはさまざまなプラットフォームで実行される可能性があります。その中にはJITコンパイラがあるものもあれば、そうでないものもあれば、まだ存在しないものもあります。 –

答えて

37

最初の例では、map.values()が1回評価されます。 Section 14.4.2 of the Java Language Specificationによると、それは同等です:秒で

for (Iterator<Object> i = map.values().iterator(); i.hasNext();) { 
    Object object = i.next(); 
    // do something with object 
} 

aList.size()は、テストが評価されるたびに呼び出されます。読みやすくするために、同様にそれをコーディングする方が良いでしょう:

for (Object object : aList) { 
    // do something with object 
} 

しかし、Android docsごとに、これは遅くなります。もう一つの方法は、 最速 、あなたがループ内でリストのサイズを変更していないと仮定すると先にループのリストの大きさを引き出すために、次のようになります。

final int size = aList.size(); 
for (int i = 0; i < size; i++) 
{ 
    object = aList.get(i); 
    //do something with i 
} 

これは、(Androidのドキュメントがリンクされ、実質的に速くなりますaListArrayListである場合には、3の因子を上回って)、LinkedListの場合は遅くなる可能性があります。それはどのような種類のList実装クラスaListが正確にあるかによって異なります。

+0

"Android docs"は壊れたリンクです。新しいものは次のとおりです:https://developer.android.com/training/articles/perf-tips.html#Loopsこれは、JITのないデバイス(「foreach」が最も速く、「foreach」がJITを搭載したデバイスの「Ted's fastes loop」と区別がつかない)で最も速いループではなく、最速のループについてTedが言ったことに少し修正を加える。 –

+0

@JustinCase - 新しい場所(および新しい情報)を追跡してくれてありがとう。私は、回答自体のリンクを更新しました。 –