2012-04-18 16 views
18

Moje pytanie dotyczy optymalizacji w java przy użyciu kompilatora Androida. Czy funkcja map.values ​​() będzie nazywać się w każdej iteracji, czy też optymalizuje ją kompilator systemu Android.metody w foreach i pętli w java

LinkedHashMap<String, Object> map; 

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

Podobnie tutaj jest inny przykład. czy aList.size() będzie nazywane każdą iteracją?

List<Object> aList; 

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

Czy to wszystko ma znaczenie, jeśli wywołuje metody w każdej iteracji? Czy Map.values ​​() i List.size() wykonują wiele operacji?

+1

To jest pytanie Java, które naprawdę nie ma nic wspólnego z Androidem. –

+0

Rozumiem zainteresowanie tym pytaniem, ale dla dowolnego celu w świecie rzeczywistym, zdecydowanie zaleciłbym profilowanie kodu przed jego optymalizacją. –

+0

@PhilippReichart - Sensownie jest zapytać, czy jeden styl kodowania ma nieodłączną przewagę nad innymi. Ponadto profilowanie ma swoje ograniczenia. Jeśli kodujesz system Android, Twój kod prawdopodobnie będzie działał na wielu różnych platformach, z których niektóre mogą mieć kompilator JIT, z których niektóre nie będą, a niektóre z nich jeszcze nie istnieją. –

Odpowiedz

37

W pierwszym przykładzie, map.values() zostanie ocenione raz. Według Section 14.4.2 of the Java Language Specification, jest równoznaczne z:

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

W drugim aList.size() będzie wywoływana za każdym razem, gdy test jest oceniany. Dla czytelności, byłoby lepiej, aby zakodować je jako:

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

Jednak za tym Android docs, będzie wolniejszy. Zakładając, że nie zmieniając rozmiar listy wewnątrz pętli, najszybciej inny sposób byłoby wyciągnąć rozmiaru listy przed pętli:

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

To będzie znacznie szybciej (Android dokumentacja związana do góry powiedzmy przez współczynnik 3), jeśli aList stanie się ArrayList, ale prawdopodobnie będzie wolniejsze (prawdopodobnie o wiele) dla LinkedList. Wszystko zależy od tego, jaka dokładnie jest klasa implementacji ListaList.

+0

"Dokumenty Android" to uszkodzony link. Oto nowy: https://developer.android.com/training/articles/perf-tips.html#Loops. Dodaje małą poprawkę do tego, co powiedział Ted o najszybszej pętli - nie jest najszybsza dla urządzeń bez JIT ("foreach" jest najszybsza, a "foreach" jest nie do odróżnienia od "pętli Teda" na urządzeniach z JIT). –

+0

@JustinCase - Dziękujemy za wyśledzenie nowej lokalizacji (i nowej informacji). Zaktualizowałem link w samej odpowiedzi. –