Если операторы внутри или снаружи циклов?

Это лучше, если я делаю это:

foreach my $item ( @array ) {
   if ( $bool ) {
     .. code ..
   }
   else {
     .. code ..
   }
}

или

if ( $bool ) {
   foreach my $item ( @array ) {
   }
}
else {
   foreach my $item ( @array ) {
   }
}
11
задан Timmy 11 February 2010 в 04:18
поделиться

6 ответов

Я бы оставил преждевременную оптимизацию в стороне.

«Преждевременная оптимизация - корень всех зол» - Дональд Кнут

В первую очередь вам следует стремиться к ремонтопригодности. Сгруппируйте их таким образом, который имеет больше смысла с учетом логической структуры кода (например, сгруппируйте связанные операторы вместе).

Если позже вы обнаружите, что производительность является проблемой, попробуйте измерить что-то вроде профилировщика, чтобы увидеть узкие места. Скорее всего, его там нет. Из Code Complete 2:

Барри Бем сообщает, что 20 процентов подпрограмм программы занимают 80 процентов времени ее выполнения. В своей классической статье "Эмпирическое исследование программ Fortran" Дональд Кнут обнаружил , что менее четырех процентов программы обычно составляет более { {1}} 50 процентов времени его работы.

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

Сосредоточение внимания на оптимизации во время начальной разработки отвлекает от достижения другой программы цели. Разработчики погружаются в анализ алгоритмов и тайные дебаты , которые в конечном итоге не приносят большой пользы для пользователя. Такие проблемы, как правильность, скрытие информации и удобочитаемость, становятся второстепенными целями, хотя производительность легче улучшить позже, чем эти другие проблемы есть. Последующая работа с производительностью обычно затрагивает менее пяти процентов кода программы. Вы бы предпочли вернуться и поработать над производительностью на пяти процентах кода или работать над удобочитаемостью на 100 процентов?

Я не говорю не надо ' t optimize , но оптимизируйте код только в конце , когда у вас есть роскошь большой картины и инструментов, которые укажут вам правильное направление.

ДОПОЛНИТЕЛЬНО: Тем не менее, чтобы ответить на вопрос о производительности:

Это ["отключение" кода] дает экономию времени примерно на 20 процентов:

Language        Straight Time    Code-Tuned Time    Time Savings
C++             2.81             2.27               19%     
Java            3.97             3.12               21%
Visual Basic    2.78             2.77               <1%
Python          8.14             5.87               28%

Особая опасность в этом случае заключается в том, что две петли должны поддерживаться параллельно. [...] вы должны помнить об изменении кода в обоих местах, что раздражает вас и создает головную боль для всех, кто должен работать с кодом.

Этот пример также иллюстрирует ключевую проблему при настройке кода: эффект любой конкретной настройки кода непредсказуем. Настройка кода привела к значительным улучшениям в трех из четырех языков, но не в Visual Basic. Выполнение этой конкретной оптимизации в этой конкретной версии Visual Basic привело бы к созданию менее удобного в обслуживании кода без какого-либо компенсирующего увеличения производительности.Общий урок состоит в том, что вы должны измерять эффект каждой конкретной оптимизации, чтобы быть уверенным в ее эффекте - никаких исключений.

Проверьте этот другой вопрос здесь, на SO. И это из первой редакции Code Complete.

18
ответ дан 3 December 2019 в 01:29
поделиться

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

2
ответ дан 3 December 2019 в 01:29
поделиться

Я предлагаю вам рассчитать и то и другое и убедиться в этом, но я не думаю, что разница будет огромной.

3
ответ дан 3 December 2019 в 01:29
поделиться

Второй вариант будет быстрее, так как сравнений гораздо меньше. -- Сравнение происходит вне цикла, а не внутри.

И поскольку переменная сравнения является инвариантом цикла, я был бы удивлен, если бы это не было также более четким кодированием.

Фактическая разница в скорости (время настенных часов) зависит от размера массива

7
ответ дан 3 December 2019 в 01:29
поделиться

Если вы оптимизируете скорость, второй (циклы foreach внутри веток if) должен быть быстрее, так как вы не будете выполнять тест в каждая итерация цикла.

5
ответ дан 3 December 2019 в 01:29
поделиться

Кажется, все застряли на проблеме производительности.

Почти всегда лучше никогда не повторять код. То есть печатать одно и то же несколько раз должно быть для вас болезненным. Поскольку вы ничего не сказали о коде в каждом из них, я предполагаю, что вы хотите делать разные вещи в каждом случае. Я предпочитаю отделить детали итерации от конкретной обработки.

 my $sub_ref = $bool ? make_true_function() : make_false_function();

 foreach my $element ( @array ) {
      $sub_ref->( $element );
      }

 sub make_true_function  { sub { ... } }
 sub make_false_function { sub { ... } }

Это может немного потерять в производительности, но на это гораздо легче смотреть, потому что это менее запутанный код. foreach не заботится ни о ветвлении, ни о том, как вы приняли решение. Это хорошо работает, когда вы хотите иметь больше веток. Пока правильная вещь отображается в $ sub_ref ​​, вы не меняете итерационный код.

5
ответ дан 3 December 2019 в 01:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: