2009-04-20 3 views
274

Можно создать дубликат:
Is there any significant difference between using if/else and switch-case in C#?«Еще если» быстрее, чем «switch() case»?

Я бывший Паскаль парень, в настоящее время обучение C#. Мой вопрос:

Является ли код ниже быстрее, чем с помощью переключателя?

int a = 5; 

if (a == 1) 
{ 
    .... 
} 
else if(a == 2) 
{ 
    .... 
} 
else if(a == 3) 
{ 
    .... 
} 
else if(a == 4) 
{ 
    .... 
} 
else 
    .... 

И переключатель:

int a = 5; 

switch(a) 
{ 
    case 1: 
     ... 
     break; 

    case 2: 
     ... 
     break; 

    case 3: 
     ... 
     break; 

    case 4: 
     ... 
     break; 

    default: 
     ... 
     break; 


} 

Какой из них быстрее?

Я спрашиваю, потому что моя программа имеет похожую структуру (много, много «else if»). Должен ли я включить их в переключатели?

+65

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

+4

См. Http://stackoverflow.com/questions/445067/if-vs-switch-speed –

+0

Переключатель быстрее, но если вы не оптимизируете жесткий цикл, это ничего не значит. Что такое 37 наносекунд против 42 наносекунд (составленные цифры)? –

ответ

466

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

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

+75

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

+58

Да, но первые 4-5 случаях приходится ловить очень близко к 100% случаев, чтобы компенсировать более медленные. – Guffa

+21

Не должны ли большинство современных компиляторов оптимизировать глубину if/else if/else if/else, если точки принятия решений в качестве таблицы переключения/перехода? Иными словами; это не имеет значения, компилятор собирается его оптимизировать, почему бы просто не написать наиболее читаемый код? –

5

Не следует испытывать затруднения, создайте функцию, которая переключает или ifelse между 5 номерами, бросает rand (1,5) в эту функцию и цикл, который несколько раз, при выборе времени.

3

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

Я говорю об общем случае здесь. Для 5 записей среднее число тестов, выполненных для ifs, должно быть меньше 2,5, если вы заказываете условия по частоте. Вряд ли узкое место, чтобы писать домой, если только в очень плотной петле.

7

Я бы сказал, что переключатель - это путь, он быстрее и лучше.

Существуют различные ссылки, такие как (http://www.blackwasp.co.uk/SpeedTestIfElseSwitch.aspx), которые показывают контрольные тесты, сравнивающие эти два.

5

Коммутатор, как правило, быстрее, чем длинный список ifs, поскольку компилятор может генерировать таблицу переходов. Чем длиннее список, тем лучше оператор switch находится над рядом операторов if.

+2

Noet, что применяется только таблица перехода (IIRC) для смежных значений. Это не редкость для компилятора, чтобы испустить сочетание таблиц перехода и breq для сложных несмежных опций. –

19

Полагая this performance evaluation, корпус переключателя быстрее.

Это вывод:

Результаты показывают, что заявление переключатель быстрее выполнить, чем если-иначе-если лестница. Это связано с возможностью компилятора оптимизировать оператор switch. В случае лестницы if-else-if код должен обрабатывать каждую инструкцию if в порядке, определенном программистом. Однако, поскольку каждый случай в выражении switch не полагается на более ранние случаи, компилятор может повторно заказать тестирование таким образом, чтобы обеспечить самое быстрое выполнение.

3

switch обычно, по возможности, преобразуется в таблицу поиска компилятором. Таким образом, поиск произвольного случая - это O (1), вместо фактического выполнения нескольких сравнений дел перед тем, как найти тот, который вы хотите.

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

2

Короткий ответ: Переключить заявление быстрее

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

Оператор switch: среднее число сравнений будет равно независимо от того, сколько у вас разных случаев. Компилятор/VM создаст «таблицу поиска» возможных опций во время компиляции.

Могут ли виртуальные машины оптимизировать оператор if аналогичным образом, если вы часто запускаете этот код?

11

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

4

Гораздо важнее преимущества производительности коммутатора (которые относительно незначительны, но стоит отметить) - проблемы читаемости.

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

147

Зачем вам все это?

99.99% времени, вам все равно.

Эти виды микро-оптимизаций вряд ли повлияют на производительность вашего кода.

Кроме того, если вам НЕОБХОДИМО заботиться, тогда вы должны выполнять профилирование производительности вашего кода. В этом случае выяснение разницы в производительности между корпусом коммутатора и блоком if-else будет тривиальным.

Редактировать: Для большей ясности: реализуйте любую конструкцию, более простую и удобную в обслуживании. Как правило, при столкновении с огромным коммутационным футляром или блокировкой if-else решение заключается в использовании полиморфизма. Найдите поведение, которое меняется и инкапсулирует его. Мне приходилось иметь дело с огромным, уродливым кодом с короткими ключами, как это раньше, и, как правило, это не так сложно упростить. Но так приятно.

+45

Я думаю, что в 100% случаев вам все равно. – Naveen

+78

Я совсем не согласен. Вы определенно должны заботиться, а не только из-за производительности, но это также влияет на читаемость кода и удобство обслуживания. И, как уже упоминалось другими, вы можете подумать о более эффективном использовании полиморфизма. –

+5

О, я согласен, что вы всегда должны заботиться о читаемости и ремонтопригодности. Правильный способ переписать огромный блок блокировки/случая, вероятно, является полиморфизмом (который, кстати, вероятно, немного медленнее, но вам все равно). Макрооптимизация (хороший дизайн) всегда лучше, чем микро-оптимизация (более быстрые операторы). – Wedge

1

Поскольку switch утверждения выражает то же намерение, как ваш if/else цепь, но в более узком, формально, ваше первое предположение должно быть то, что компилятор сможет оптимизировать это лучше, так как он может сделать больше выводов о условия, помещенные в ваш код (т. е. только одно состояние может быть истинным, сравниваемое значение является примитивным типом и т. д.). Это довольно безопасная общая истина, когда вы сравниваете две аналогичные структуры языка для производительности во время выполнения.

4

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

Обычно я предпочитаю использовать переключатель.Таким образом, код просто читать.

1

см http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.switch%28VS.71%29.aspx

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

Смежные вопросы