2009-11-25 2 views
18

Я перебираю массив и сортирую его по значениям в дни недели.Что происходит быстрее: многие ifs, а если?

Для этого я использую множество заявлений if. Имеет ли значение скорость обработки, если я использую много if s, по сравнению с набором команд else if?

+1

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

+0

Существует массовое изменение функции при переходе от многих операторов if к одному оператору if-elseif. Подумайте о том, что действительно делает ваш код. –

ответ

41

Да, использовать еще, если, рассмотрим следующий код:

if(predicateA){ 
    //do Stuff 
} 
if(predicateB){ 
    // do more stuff 
} 

из

if(predicateA){ 
    // 
} 
else if(predicateB){ 
    // 
} 

во втором случае, если предикат А является истинным, предикат B (и любые другие предикаты) не нужно будет оценивать (и, следовательно, весь код будет выполняться быстрее), тогда как в первом примере, если предикат A является t rue, predicateB всегда будет оцениваться, и вы также можете получить неожиданные сюрпризы, если predicateA и predicateB не являются взаимоисключающими.

+1

Это должно быть существенное количество условий, чтобы действительно увидеть разницу в производительности, но +1, как если бы все было правильно. – James

+5

Собственно, ваш пример неверен, потому что они не будут делать то же самое, если оба PredicateA и PredicateB могут ocurre. вы выполните только первый и выйдете. в то время как первый код будет выполнять оба. –

17

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

Ваш алгоритм сортировки, скорее всего, станет источником проблемы с производительностью. Какой алгоритм сортировки вы выберете, будет критически, не так много «ifs» и «else if».

UPDATE:

Точки, сделанные другими о «еще, если» быть лучшим выбором, из-за его раннего выхода и эксклюзивных логических характеристик, позволяют предположить, что она должна быть предпочтительнее, чем «если» в этом случае.

Но точка зрения на выбор алгоритма все еще стоит - если только ваш набор данных очень мал.

Очевидно, что O (log n) будет лучше, чем O (n^2), но размер массива также имеет значение. Если у вас есть только несколько элементов, вы можете не заметить разницу. В этом случае наилучшим выбором может быть кодирование неэффективного метода в самом чистом, наиболее читаемом, наиболее легко понятном с первого взгляда.

:
+5

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

+1

Согласен, хороший момент, Янник. – duffymo

+1

Не было бы еще и чтения чтения if-else, а также предоставления компилятору приличного намека? –

3

else if будет быстрее в том смысле, что вы сравниваете, пока не нажмете условие, которое разрешает true, и вы пропустите оставшуюся часть if s.

Также рассмотрите возможность переупорядочения в порядке убывающей частоты.

И используя оператор switch в зависимости от типа данных объекта, который вы сравниваете.

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

7

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

switch ($day) 
{ 
    case "Monday": 
     // do something with Monday 
     break; 
    case "Tuesday": 
     // do something with Tuesday 
     break; 
    case "Wednesday": 
     // do something with Wednesday 
     break; 
} 
+0

Переключатель, безусловно, повышает производительность над многими ifs! – Daniel

2

Если значения являются целыми числами, вы можете добиться оптимизации с помощью поиска в таблице. Например. скажем, что у вас 256 значений, которые каким-то образом отображались на 7 дней, вы можете настроить массив с 256 ячейками, и каждая ячейка содержала желаемый день недели.Тогда вместо того, чтобы:


if (value == 0) { 
    dayofweek = 1; 
} else if (value == 1) { 
    dayofweek = 2; 
} else if (value == 2) { 
    dayofweek = 3; 
} else if ... 

.. вы могли бы ..


dayofweek = lookuparray[value]; 

Конечно, если вы используете этот метод, то вы должны проверить границы стоимости первой.

0

В общем, стиль «else if» может быть быстрее, потому что в серии ifs каждое условие проверяется один за другим; в цепочке «else if», когда одно условие согласовано, остальные обходят.

Быстрее всего будет отправка таблицы, и это то, что оператор switch оптимизируется, когда в нем достаточно случаев (если в коммутаторе имеется несколько случаев, он преобразуется в серию проверок if-else в полученный машинный код).

0

Решение использовать многие операторы if или один if-elseif-elseif ... не должно опираться на производительность, поскольку это решение предполагает массовый поток программы.

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

Его дизайн вопрос, а не один.

9

Вы можете посмотреть на phpbench

Но, честно говоря, если вы хотите оптимизировать на этом уровне, вы можете узнать что-то другое, чем PHP.

alt text

0

я бы поставил еще один голос в течение выбирают для переключателя() заявление вместо этого.

2

Я сделал тест, если есть истинная разница между последовательным, если(), и если(), а затем несколькими ElseIf()

Я положил большую строку и сделал около 20 StrPos() каждый раз (X100 000) с этими двумя методами, и он показал этот результат:

Try 1 : 0.5094 (including elseif) 
Try 2 : 0.6700 (including only if) 

Нет сомнений. Я уже знал, что sucessive elseif() были быстрее, хотя есть возвращение в середине; по-прежнему полезно добавить некоторые статистические данные в ответ.

0

Этот вопрос особенно интересен, когда блок if возвращает таким образом завершение метода. Это также относится непосредственно к тому, как работают компараторы в Java.

Я, таким образом, работать каждый метод (пыльник) 250.000.000 раз и результаты таковы:

two values if/else - 6.43 millis 
three values if/else/if - 8.66 millis 
three values if/if  - 9.01 millis 

Хотя в худшем случае требуется в 1,4 раза больше, чем лучший друг сделать уведомление, что это суммарная сумма итерации каждого из этих методов 250 миллионов раз. Предполагая, что для восприятия задержки потребуется 100 мс, а наихудшая/лучшая разница - 2,58 миллиса, это означало бы, что вам понадобится почти триллион (1000 * 1000 миллионов) итераций, чтобы понять разницу между различными методами.

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

// methods used to measure difference between if and if/else 

/** equality is not important **/ 
private static int comparatorOfIfElse(int a, int b) { 
    if(a < b) return -1; 
    else return 1; 
} 

/** equality is taken into account using if/else **/ 
private static int comparatorOfIfElseIf(int a, int b) { 
    if(a < b) return -1; 
    else if(a > b) return 1; 
    return 0; 
} 

/** equality is taken into account using only if **/ 
private static int comparatorOfIf(int a, int b) { 
    if(a < b) return -1; 
    if(a > b) return 1; 
    return 0; 
} 
Смежные вопросы