Самый быстрый способ перебора массива в Java: переменная цикла против улучшенной для оператора [duplicate]

This question already has an answer here:

Is there a performance difference between a for loop and a for-each loop? 16 answers

В Java быстрее перебирать массив старомодным способом,

<code>for (int i = 0; i < a.length; i++)
    f(a[i]);
</code>

Или используя более краткую форму,

<code>for (Foo foo : a)
    f(foo);
</code>

Для ArrayList ответ тот же?

Конечно, для огромного объема кода приложения ответ не имеет заметных различий, поэтому для удобства чтения следует использовать более лаконичную форму. Однако контекст, на который я смотрю, - это сложные технические вычисления, в которых операции должны выполняться миллиарды раз, поэтому даже незначительная разница в скорости может оказаться значительной.

 Deestan03 сент. 2012 г., 14:21
Почему бы не запустить тест? Гораздо точнее, чем обсуждение.
 RichardOD17 июн. 2009 г., 13:12
Это былоasked before.
 user20742130 дек. 2013 г., 04:51
Вы вряд ли заметите разницу, еслиf() исчезающе коротка
 Albert Hendriks01 мар. 2013 г., 10:54
Это не массив. В разделе «заданный перед вопросом» внутренне итератор будет создан с циклом foreach, тогда как здесь он не будет соответствовать ответам здесь.

Ответы на вопрос(5)

микро-оптимизации, Это действительно не имеет значения. Стилистически я всегда предпочитаю второе, потому что оно более лаконично, если только вам не нужен счетчик циклов для чего-то другого. И этоfar more important than this kind of micro-optimizationудобочитаемость

При этом для ArrayList не будет большой разницы, но LinkedList будет намного эффективнее со вторым.

 17 июн. 2009 г., 14:11
Второе также ограничено таким образом, потому что массивы имеют максимальное количество элементов Integer.MAX_VALUE, а ArrayList поддерживается массивом.
 17 июн. 2009 г., 13:48
первый стиль ограничен числом итераций Integer.MAX, а второй - нет.
 17 июн. 2009 г., 13:18
Он не будет использовать итератор для массива.

версии виртуальной машины, процессора, скорости памяти, кэша и т. Д. Таким образом, вы должны измерить его для вашей конкретной платформы.

Лично я предпочел бы второй вариант, потому что намерение более понятно. Если производительность становится проблемой, я в любом случае могу оптимизировать ее позже - если этот код действительно важен для производительности всего приложения.

вас достаточно большой набор данных).

Решение Вопроса

это не имеет значения - в любом случае расширенный цикл for использует доступ к массиву.

Например, рассмотрим этот код:

public static void main(String[] args)
{
    for (String x : args)
    {
        System.out.println(x);
    }
}

Когда декомпилируется сjavap -c Test мы получаем (дляmain метод):

public static void main(java.lang.String[]);
  Code:
   0:   aload_0
   1:   astore_1
   2:   aload_1
   3:   arraylength
   4:   istore_2
   5:   iconst_0
   6:   istore_3
   7:   iload_3
   8:   iload_2
   9:   if_icmpge   31
   12:  aload_1
   13:  iload_3
   14:  aaload
   15:  astore  4
   17:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   20:  aload   4
   22:  invokevirtual   #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   25:  iinc    3, 1
   28:  goto    7
   31:  return

Теперь измените его, чтобы использовать явный доступ к массиву:

public static void main(String[] args)
{
    for (int i = 0; i < args.length; i++)
    {
        System.out.println(args[i]);
    }
}

Это декомпилируется в:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   aload_0
   4:   arraylength
   5:   if_icmpge   23
   8:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   11:  aload_0
   12:  iload_1
   13:  aaload
   14:  invokevirtual   #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   17:  iinc    1, 1
   20:  goto    2
   23:  return

В расширенном цикле for немного больше установочного кода, но в основном они делают то же самое. Итераторы не участвуют. Кроме того, я ожидаю, что они получат JITted для еще более похожего кода.

Предложение: если вы действительно думаете, что это может иметь существенное значение (что было бы толькоever делайте, если тело цикла абсолютно крошечное), тогда вы должны сравнить его с вашим реальным приложением. Это единственная ситуация, которая имеет значение.

for(ClassOfElement element : listOfElements) {
  System.out.println(element.getValue());
}

Ответили раньше:

Есть ли разница в производительности между циклом for и циклом for-each?

Ваш ответ на вопрос