Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

о

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

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

Ответ 2

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

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

ОБНОВЛЕНИЕ:

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

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

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

Ответ 3

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

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

alt text

Ответ 4

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

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

Ответ 5

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

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

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

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

Ответ 6

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

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

Ответ 7

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

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

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

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

Ответ 8

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

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

Ответ 9

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

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

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

Ответ 10

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

Ответ 11

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