Что быстрее: многие ifs, а если?

Я повторяю массив и сортирую его по значениям в дни недели.

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

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

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

из

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

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

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

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

ОБНОВИТЬ:

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

Но вопрос о выборе алгоритма все еще стоит – если ваш набор данных не очень мал.

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

Вы можете взглянуть на phpbench

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

alt text

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

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

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

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

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

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

Если значения являются целыми числами, вы можете добиться оптимизации, используя поиск в таблице. Например, скажем, что у вас есть 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]; 

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

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

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

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

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

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

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

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

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

Это вопрос дизайна, а не один.

Я бы поместил еще один голос для выбора инструкции switch ().

Этот вопрос особенно интересен, когда блок 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; }