2012-04-18 11 views
18

Mi pregunta es sobre la optimización en Java utilizando el compilador de Android. Will map.values ​​() en lo sucesivo se llamará en cada iteración, o el compilador de Android lo optimizará.métodos en foreach y para bucles en java

LinkedHashMap<String, Object> map; 

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

Igual que aquí hay otro ejemplo. se llamará aList.size() a cada iteración?

List<Object> aList; 

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

Y después de todo esto, ¿realmente importa si llama a los métodos cada iteración? ¿Map.values ​​() y List.size() hacen gran cosa?

+1

Esta es una pregunta de Java que realmente no tiene nada que ver específicamente con Android. –

+0

Entiendo el interés en esta pregunta, pero para cualquier propósito del mundo real, recomiendo encarecidamente el código de perfil antes de optimizarlo. –

+0

@PhilippReichart - Tiene mucho sentido preguntar si un estilo de codificación tiene una ventaja de rendimiento inherente sobre otro. Además, la creación de perfiles tiene sus límites. Si está codificando para Android, es probable que su código se ejecute en una amplia variedad de plataformas, algunas de las cuales pueden tener un compilador JIT, algunas de las cuales no, y algunas de las cuales ni siquiera existen todavía. –

Respuesta

37

En el primer ejemplo, map.values() se evaluará una vez. De acuerdo con la Section 14.4.2 of the Java Language Specification, es equivalente a:

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

En el segundo, aList.size() se llamará cada vez que se evalúa la prueba. Para facilitar la lectura, sería mejor para codificar como:

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

Sin embargo, por el Android docs, esto será más lenta. Suponiendo que no va a cambiar el tamaño de la lista dentro del bucle, el más rápido otra forma sería la de sacar el tamaño de la lista por delante del bucle:

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

Ésta será sustancialmente más rápido (la documentación de aplicaciones vinculadas por encima de decir por un factor de 3) si aList pasa a ser un ArrayList, pero es probable que sea más lento (posiblemente por mucho) para un LinkedList. Todo depende exactamente de qué tipo de implementación es List clase aList.

+0

"Android Docs" es un enlace roto. Aquí está el nuevo: https://developer.android.com/training/articles/perf-tips.html#Loops. Agrega una pequeña corrección a lo que Ted dijo sobre el ciclo más rápido: no es el más rápido para dispositivos sin JIT ("foreach" es el más rápido, y "foreach" es indistinguible del "lazo de fas de Ted" en dispositivos con JIT). –

+0

@JustinCase - Gracias por rastrear la nueva ubicación (y la nueva información). Actualicé el enlace en la respuesta en sí. –

Cuestiones relacionadas