2012-04-18 5 views
18

Meine Frage bezieht sich auf die Optimierung in Java mit dem Android-Compiler. Will map.values ​​() im Folgenden bei jeder Iteration aufgerufen werden, oder wird der Android-Compiler es optimieren.Methoden in foreach und für Schleifen in Java

LinkedHashMap<String, Object> map; 

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

Auch hier ist ein weiteres Beispiel. wird aList.size() jede Iteration aufgerufen?

List<Object> aList; 

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

Und nach all dem, ist es wirklich wichtig, wenn es jeder Iteration die Methoden aufruft? Machen Map.values ​​() und List.size() viel aus?

+1

Dies ist eine Java-Frage, die wirklich nichts mit Android zu tun hat. –

+0

Ich verstehe das Interesse an dieser Frage, aber für jeden realen Zweck, würde ich stark vorschlagen, Code vor der Optimierung zu profilieren. –

+0

@PhilippReichart - Es macht durchaus Sinn zu fragen, ob ein Kodierungsstil einen inhärenten Leistungsvorteil gegenüber einem anderen hat. Auch das Profiling hat seine Grenzen. Wenn Sie für Android codieren, wird Ihr Code wahrscheinlich auf einer Vielzahl von Plattformen ausgeführt, von denen einige einen JIT-Compiler haben können, von denen einige nicht und einige sogar noch nicht existieren. –

Antwort

37

Im ersten Beispiel wird map.values() einmal ausgewertet. Nach den Section 14.4.2 of the Java Language Specification, ist es gleichbedeutend mit:

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

Im zweiten aList.size() wird jedes Mal aufgerufen werden, der Test ausgewertet wird. Zur besseren Lesbarkeit wäre es besser, es zu kodieren als:

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

jedoch je den Android docs, dies wird langsamer sein. Unter der Annahme, dass Sie nicht die Liste Größe innerhalb der Schleife zu ändern, die schnellsten ein anderer Weg wäre, um die Liste Größe ziehen vor der Schleife:

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

Diese wesentlich schneller sein wird (die Android docs verknüpft zu sagen um einen Faktor von 3) wenn aList zufällig eine ArrayList ist, aber wahrscheinlich langsamer (möglicherweise durch eine Menge) für eine LinkedList ist. Es hängt alles davon ab, welche Art von List Implementierungsklasse aList ist.

+0

"Android Docs" ist ein defekter Link. Hier ist der neue: https://developer.android.com/training/articles/perf-tips.html#Loops. Es fügt eine kleine Korrektur zu dem hinzu, was Ted über die schnellste Schleife gesagt hat - es ist nicht die schnellste für Geräte ohne JIT ("foreach" ist die schnellste und "foreach" ist nicht von "Teds schnellste Schleife" auf Geräten mit JIT zu unterscheiden). –

+0

@JustinCase - Vielen Dank für das Auffinden des neuen Standorts (und der neuen Informationen). Ich habe den Link in der Antwort selbst aktualisiert. –

Verwandte Themen