2014-11-14 1 views
0

Является ли это использование элементов ArrayList:оптимизация игры в Java относительно ArrayList <Object> элементов литья другой переменной внутри для цикла

for(int i=0; i<array_list.size(); i++){ 
     Object obj = array_list.get(i); 
     //do **lots** of stuff with **obj** 
    } 

быстрее, чем это:

for(int i=0; i<array_list.size(); i++){ 
     //do **lots** of stuff with **array_list.get(i)**; 
    } 
+0

Не могли бы вы придумать лучшее название? –

+0

Что вы измерили? – RobAu

+1

JIT может оптимизировать вторую версию, чтобы она была эквивалентна первой. Качество кода мудрено, первое лучше, потому что вы можете дать вашему объекту описательное имя. – Cubic

ответ

1

Это зависит от того, как много раз array_list.get(i) вызывается во втором коде. Если он вызывается только один раз, нет никакой разницы между обоими методами.

Если оно вызывается несколько раз, сохранение значения в переменной может быть более эффективным (это зависит от компилятора и оптимизации JIT).

Пример сценария, где первый метод может быть более эффективным, скомпилированы с использованием javac компилятор Oracle JDK, в предположении, список содержит String объекты:

for(int i=0; i<array_list.size(); i++){ 
    String obj = array_list.get(i); 
    System.out.println(obj); 

    if(!obj.isEmpty()) { 
     String o = obj.substring(1); 
     System.out.println(o + obj); 
    } 
} 

В этом случае obj сохраняется в локальной переменной и загружается каждый раз, когда Это использовано.

for(int i=0; i<array_list.size(); i++){ 
    System.out.println(array_list.get(i)); 

    if(!array_list.get(i).isEmpty()) { 
     String o = array_list.get(i).substring(1); 
     System.out.println(o + array_list.get(i)); 
    } 
} 

В этом случае, множественный invokation для List.get наблюдаются в байт-код.

+4

даже в последнем случае я сомневаюсь, что это будет иметь значение, как только JIT компилирует этот метод ... – assylias

+0

много раз я его использую. более 100 раз – gogonapel

+1

@gogonapel Я думаю, что первый подход будет лучше, поскольку вы не будете иметь вызовы методов. –

1

Разница в производительности между получением один раз и локальной переменной почти всегда пренебрежимо мала. Но ... если вы настаиваете на делать это хардкорный способом, это быстрый путь:

ArrayList<Object> array_list = ... 
// cache list.size() in variable! 
for (int i=0, e=array_list.size(); i < e; ++i) { 
    // get object only once into local variable 
    Object object = array_list.get(i); 
    // do things with object 
} 

Это кэширует списки размера в локальные переменные е, чтобы избежать вызова array_list.size() в каждом итерации цикла, а также каждый элемент цикла, чтобы избежать вызовов get (index). Имейте в виду, что все, что вы на самом деле do с объектами в цикле, скорее всего, будет на порядок дороже, чем сам цикл.

Поэтому предпочитает читаемость кода и просто не использовать расширенный синтаксис петли:

ArrayList<Object> array_list = ... 
for (Object object : array_list) { 
    // do things with object 
} 

Нет суеты, короткой и четкую. В большинстве случаев это намного больше, чем несколько сохраненных тактовых циклов.

Смежные вопросы