2009-07-15 2 views
0

Есть ли разница во времени выполнения следующих двух фрагментов?есть разница во времени выполнения:

SNIPPET 1:

for (Object obj : collection) { 
    step1(obj); 
    step2(obj); 
    step3(obj); 
} 

SNIPPET 2:

for (Object obj : collection) { 
    step1(obj); 
} 

for (Object obj : collection) { 
    step2(obj); 
} 

for (Object obj : collection) { 
    step3(obj); 
} 
+0

В зависимости от реализации «step1», «step2» и «step3» компилятор может скомпилировать последний тот же (байтовый) код как первый. Но почему бы тебе не разойтись? – Stephan202

+0

Нет, это не так. Вызовы выполняются в разных порядках. Если объектами являются a, b, c и т. Д. В первом примере вызовы являются a1, a2, a3, b1, b2, b3 и т. Д., Но они являются a1, b1, a2, b2, a3, c3 во втором примере. – FogleBird

+0

У них такой же Big-O, но в отличие от большинства претензий ниже, невозможно знать, что будет быстрее во время выполнения, не зная, что делают шаги step1, step2 и step3. Когерентность кодового кеша, согласованность кэша данных, точность предсказания отрасли ... любое количество вещей, которые могут изменить производительность во время выполнения. Сроки сами по себе являются единственным способом «знать», и даже в этом случае результаты по-прежнему зависят от вашего оборудования. –

ответ

1

Конечно. Первый фрагмент повторяется через коллекцию только один раз, а второй фрагмент - 3 раза. Второй фрагмент также нарушает принцип DRY.

+0

Интуитивно кажется, что вы правы, но я не вижу разницы в производительности исполнения. Каждый фрагмент выполняет шаги 3N, где N - размер коллекции. Некоторые языки имеют накладные расходы, связанные с итерацией, но если мы игнорируем это, я не вижу огромной разницы между ними. – os111

+0

Ну, если вы проигнорируете разницу в итерации, какая еще разница будет? Тогда они такие же. – ryeguy

+0

+1 для сухих ...плюс, если это измененная коллекция (или какой-то объект, который реализует Iterable, но на самом деле это не коллекция), вы можете получить разные операции над каждым объектом – kdgregory

0

Если вы спрашиваете о каком-либо языке, SNIPPET 1 должен быть быстрее.

0

Итерации производятся 3 раза.

Также вы будете называть step1 (obj) n раз, затем step2 (obj) n раз, затем step3 (obj) n раз.

0

Если один из вызовов метода вызовет исключение, скажем, шаг1 в середине итерации, то вторая версия остановится раньше первой. Но если step3 создает исключение для первого элемента, то первая версия выполняется быстрее. Таким образом, две версии не эквивалентны семантически.

0

Есть ли разница? Конечно.

Есть ли разница, которая имеет значение? Все это зависит.

Если StepN() занимает несколько наносекунд, то да. В противном случае, вероятно, нет.

0

Вы спрашиваете конкретно о производительности?

В этом случае, ответ зависит от того, насколько быстро коллекции в итератора: если Next() является дорогостоящей операцией для этого конкретного итератора, то вы платите, что стоимость N раз в первой версии и 3N раз в последнем. Это незначительно, если ваша коллекция является вектором, но более серьезной, когда ваша коллекция, скажем, является интерфейсом к некоторой медленной операции ввода-вывода файлов.