Если заявления внутри или снаружи циклы? - PullRequest
11 голосов
/ 11 февраля 2010

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

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

или

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

Ответы [ 6 ]

18 голосов
/ 11 февраля 2010

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

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

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

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

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

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

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

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

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

Этот ["выключающий" код] хорош для экономии времени примерно на 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.

7 голосов
/ 11 февраля 2010

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

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

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

5 голосов
/ 14 февраля 2010

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

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

 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 голосов
/ 11 февраля 2010

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

3 голосов
/ 11 февраля 2010

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

2 голосов
/ 11 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...