Что лучше switch или if else
Эстетическая красота: Switch vs If
Вводная
Немного нюансов
Речь ниже пойдет о сравнении оператора switch и его конкретной реализаций на языке Java и операторами if в виде оппонентов этой конструкции. О том, что у оператора switch имеется туз в рукаве — производительность (за редким исключением), пожалуй, знает каждый и этот момент рассматриваться не будет — так как крыть его нечем. Но все же, что не так?
1. Многословность и громоздкость
Среди причин, отталкивающих меня от использования оператора switch — это многословность и громоздкость самой конструкции, только взгляните — switch, case, break и default, причем опускаю за скобки, что между ними, наверняка, еще встретится return и throw. Не подумайте, что призываю не использовать служебные слова языка java или избегать их большого количества в коде, нет, лишь считаю, что простые вещи не должны быть многословными. Вот небольшой пример того, о чем говорю:
Итого для меня: switch/case/default VS if.
Если спросить, кому какой нравится больше код, то большинство отдаст предпочтение 1ому варианту, в то время как по мне, он — многословный. Речь о рефакторинге кода здесь не идет, все мы знаем, что можно было бы использовать константу типа EnumMap или IdentityHashMap для поиска списка по ключу channel или вообще убрать нужные данные в сам Channel, хотя это решение дискуссионное. Но вернемся.
2. Отступы
Возможно в академических примерах использование оператора swicth — это единственная часть кода, но тот код, с которым приходится сталкиваться, поддерживать — это более сложный, обросший проверками, хаками, где-то просто предметной сложностью код. И лично меня, каждый отступ в таком месте напрягает. Обратимся к ‘живому’ примеру (убрал лишнее, но суть осталась).
Итого для меня: 5 отступов VS 2.
Но опять, кому какой нравится вариант? Большинство отдаст предпочтение getReference1.
Отдельно стоит отметить, что количество отступов еще зависит от выбранного стиля форматирования кода.
3. Проверка на null
Если используется оператор switch со строками или енумами параметр выбора необходимо проверять на null. Вернемся к getTypes примерам.
Итого для меня: лишний код.
Даже если Вы абсолютно уверенны сейчас в том, что null ‘не придет’, это абсолютно не значит, что так будет всегда. Я проанализировал корпоративный багтрэк и нашел этому утверждению подтверждение. Справедливости ради стоит отметить, что структура кода выраженная через if не лишена этой проблемы, зачастую константы для сравнения используются справа, а не слева, например, name.equals(«John»), вместо «John».equals(name). Но в рамках данной статьи, по этому пункту, хотел сказать, что при прочих равных, подход со switch раздувается проверкой на null, при if же проверка не нужна. Добавлю еще, что статические анализаторы кода легко справляются с возможными null-багами.
4. Разношерстность
Очень часто, при длительном сопровождении кода, кодовая база раздувается и можно легко встретить код, похожий на следующий:
Итого для меня: разный стиль.
Раньше был ‘чистенький’ switch, а теперь switch + if. Происходит, как я называю, смешение стилей, часть кода ‘выбора’ выражена через switch, часть через if. Разумеется никто не запрещает использовать if и switch вместе, если это не касается операции выбора/под выбора, как в приведенном примере.
5. Чей break?
При использовании оператора switch, в case блоках может появиться цикл или на оборот, в цикле — switch, со своими прерываниями процесса обработки. Вопрос, чей break, господа?
Итого для меня: читаемость кода понижается.
Если честно, встречались и куда более запутанные примеры кода.
6. Неуместность
В java 7 появилась возможность использовать оператор switch со строками. Когда наша компания перешла на java 7 — это был настоящий Switch-Бум. Может по этому, а может и по другой причине, но во многих проектах встречаются похожие заготовки:
Итого для меня: появляются неуместные конструкции.
7. Гламурный switch под аккомпанемент хардкода
Немного юмора не помешает.
Заключение
Я не призываю Вас отказываться от оператора switch, местами он действительно хорош собой и лапша из if/if-else/else та еще каша. Но черезмерное его использование где ни попадя, может вызывать недовольство у других разработчиков. И я один из них.
Отдельно хотелось отметить, что c точки зрения понимания кода, у меня нет никаких проблем с switch/case — смысл написанного ясен, но вот с точки зрения восприятия эстетической красоты — есть.
И напоследок. Используйте то, что Вам приходится по душе, опуская за скобки навязанные мнения, главное, чтобы Ваш код был простым, рабочим, красивым и надежным. Всего хорошего.
if \ else vs. switch \ case в C#
Что лучше использовать: if\else или switch\case?
3 ответа 3
Ответ выше не совсем корректный, даже учитывая комментарий.
Если значения лежат рядом, например:
В таком случае компилятор генерирует таблицу переходов (jump table) (IL-код):
Как видно, «дырки» заполнились переходами за конец конструкции switch : IL_009a
Если расстояние между значениями слишком большое для построение одной таблицы, компилятор может разделить их на 2+ таблицы. Например:
Посмотрим что будет в общем случае. Я взял 20 случайных чисел:
В таком случае компилятор их сортирует, и ищет бинарным поиском:
Дополнение для String :
Я попытался создать очень большой switch на 60 строк, но ничего не изменилось.
Оба условных оператора работают с одинаковой скоростью. Так как на уровне машинных команд они преобразуются в одни и те же инструкции.
Выбирать имеет смысл только по вкусу и по задаче.
switch может работать только с одной переменной. У if таких ограничений нет.
На мой взгляд, язык C# слишком высокоуровневый для такого рода оптимизаций.
Пишите читаемый код 😉
Вы задаётесь неправильным вопросом.
Если ваша задача — ускорить вашу программу, то решением этой задачи никогда не будет «заменить свитч на последовательность ифов» или наоборот. Ускорение программы проводится на уровне используемых алгоритмов и структур данных.
Тот факт, что один или другой вариант в тех или иных условиях, на той или иной версии компилятора выполняется на несколько наносекунд быстрее, не стоит потраченных на него байт текста.
Во-первых, вы должны помнить, что ваша главная задача — не выиграть 10 тактов процессора (несчастное переключение контекста стоит намного больше!), а сделать вашу программу понятной. Поэтому вы должны использовать switch там, где это прибавляет читаемости коду, там, где это соответствует тому, что именно вы хотите сказать этим кодом. И использовать if там, где это лучше отражает вашу мысль.
Ну и во-вторых, то, что на одной версии компилятора один из методов выражения одной и той же идеи компилируется в более быстрый код, чем другой метод — штука временная и преходящая. Помните, что в C++ сначала рекомендовалось возвращать значения по ссылке для скорости, а затем пришёл тренд «want speed? pass by value!», и наверняка это поменялось сейчас ещё раз.
Поскольку код имеет одинаковый смысл, то в любом из его вариантов рано или поздно он будет компилироваться в одно и то же. JIT-компилятор C# покамест не генерирует одинаковый объектный код для этих двух случаев, а вот компиляторы C++ уже умеют.
Итак, то, какая из имплементаций скорее, а какая медленнее — это не абсолютное понятие.
Вы не должны жертвовать читаемостью кода ради сиюминутной мизерной выгоды. Пишите не «как скорее», а «как правильнее». Расходы на поддержку плохо написанного кода несравнимо больше выгод от микрооптимизаций.
If или switch().case. Что быстрее
switch case 1 ИЛИ 2
делаю разбор вводимых команд, некоторые обрабатываются похоже, команды однобуквенные, разбираю.
Решение
В первом случае все if будут проверяться всегда.
Во втором случае все case будут пройдены только при а = 4. Например, если а = 2, то отработает только первый case и мы выйдем по break. При а = 3 отработают два первых case.
Решение
if выполняет столько сравнений, сколько у вас вариантов. switch вероятнее всего сделает двоичный поиск и выполнит число сравнений равное двоичному логарифму от числа вариантов. Если внутре у ней неонка jmp по табличке, то и вовсе в одну команду уложится.
Ну и каждое ветвление награждает вас 50% бонусом к шансу получить неверным предсказанием перехода по башке. Что не лучшим образом сказывается на производительности. Поэтому лучше их без нужды не плодить.
Это ты еще duff device не видел
——
А вообще все эти рассуждения о скорости не имеют смысла без привязки к конкретному компилятору и его оптимизации. Если хочется адекватных оценок, то берем компилятор, конкретные ключи компиляции, смотрим ассемблер и делаем выводы. Все остальное от лукавого.
при очень разреженном
при case 0 1 2 3 4
скорее всего switch превратится в таблицу переходов
у Evg в блоге была статья на эту тему
если найду кину ссылку
Добавлено через 1 минуту
очень даже распространенная практика «проваливания»
кстати в шарпе её кастрировали и приходится дублировать код
чаще да
но посмотри на код по ссылке
Добавлено через 2 минуты
Ещё неплохой способ «we need to go deeper»:
Статический хеш или switch-case/if-else для выбора
Добрый день. Положим есть такой код:void parseByType(const QString &data, const QString &type) <.
Что быстрее switch(enum) или if else? в чем преимущество/недостаток в использовании switch заявление против if/else в C#. Я не могу представить, что есть такая большая разница, кроме, возможно, внешнего вида вашего кода. есть ли причина, по которой результирующая производительность IL или связанная с ней производительность среды выполнения будет радикально отличаться? оператор SWITCH создает только ту же сборку, что и IFs в режиме отладки или совместимости. В выпуске он будет скомпилирован в таблицу переходов(через инструкцию MSIL’ switch’), которая является O (1). но если количество условия достаточно велики, чтобы покрыть накладные расходы, компилятор C# создаст объект HashTable, заполнит его строковыми константами и сделает поиск в этой таблице с последующим переходом. Поиск Hashtable не является строго O(1) и имеет заметные постоянные затраты, но если количество меток case велико, это будет значительно быстрее, чем сравнение с каждой Строковой константой в IFs. чтобы подвести итог, если количество условий больше 5 или около того, предпочтите переключиться, если в противном случае используйте все, что выглядит лучше. в целом (учитывая все языки и все компиляторы) оператор switch иногда может быть более эффективным, чем оператор if / else, потому что компилятору легко генерировать таблицы перехода из операторов switch. Можно сделать то же самое для операторов if / else, учитывая соответствующие ограничения, но это намного сложнее. в случае C# это также верно, но по другим причинам. с большим количеством строк, то есть значительное преимущество в производительности для использования оператора switch, поскольку компилятор будет использовать хэш-таблицу для реализации перехода. с небольшим количеством строк, производительность между двумя одинаково. Это потому, что в этом случае компилятор C# не генерирует таблицы переходов. Вместо этого он генерирует MSIL, который эквивалентен блокам IF / ELSE. существует инструкция MSIL» оператор switch», которая при jitted будет использовать таблицу переходов для реализации оператор Switch. Однако он работает только с целочисленными типами (этот вопрос задает строки). для небольшого количества строк компилятору более эффективно генерировать блоки IF / ELSE, а затем использовать хэш-таблицу. когда я впервые заметил это, я предположил, что, поскольку блоки IF / ELSE использовались с небольшим количеством строк, компилятор сделал то же самое преобразование для большого количества строк. Это было неправильно. «ИМА» была достаточно любезна, чтобы указать мне на это (ну. он не был добрым, но он был прав, а я ошибался, что является важной частью) Я также сделал костяное предположение об отсутствии инструкции «switch» в MSIL (я подумал, если есть примитив switch, почему они не используют его с хэш-таблицей, поэтому не должно быть примитива switch. ). Это было неправильно, и невероятно глупо с моей стороны. И снова » ИМА » указал мне на это. Я сделал обновления здесь, потому что это самый высокий рейтинг должности и принятый ответ. тем не менее, я сделал это сообщество Wiki, потому что я считаю, что не заслуживаю репутации за то, что ошибся. Если у вас есть шанс, пожалуйста, проголосуйте за сообщение ima. три причины предпочесть switch : компилятор, нацеленный на собственный код, часто может скомпилировать оператор switch в одна условная ветвь плюс косвенный скачок тогда как последовательность if s требует последовательность условных ветвей. В зависимости от плотности случаев было написано много научных работ о том, как эффективно компилировать операторы case; некоторые из них связаны с компилятор lcc страница. (У Lcc был один из самых инновационных компиляторов для коммутаторов.) оператор switch является выбор среди взаимоисключающих альтернатив и синтаксис переключателя делает этот поток управления более прозрачным для программиста затем гнездо операторов if-then-else. на некоторых языках, включая определенно ML и Haskell,компилятор проверяет, не пропустили ли вы какие-либо случаи. Я рассматриваю эту функцию как одно из основных преимуществ ML и Haskell. Я не знаю, Может ли C# это сделать. анекдот: на лекции, которую он прочитал о получении награды за достижения в жизни, я слышал, как Тони хор сказал, что из всего, что он сделал в своей карьере, было три, которыми он больше всего гордился: На самом деле, оператор switch более эффективен. Компилятор оптимизирует его до таблицы поиска, где с помощью операторов if/else он не может. Недостатком является то, что оператор switch нельзя использовать со значениями переменных. компилятор собирается оптимизировать почти все в один и тот же код с незначительными различиями (кнут, кто-нибудь?). разница в том, что оператор switch чище, чем пятнадцать, если еще заявления нанизанные. друзья не позволяют друзьям складывать операторы if-else. Я не видел, чтобы кто-то еще поднимал (очевидно?) укажите, что предполагаемое преимущество эффективности оператора switch зависит от того, что различные случаи примерно одинаково вероятны. В случаях, когда одно (или несколько) значений гораздо более вероятно, лестница if-then-else может быть намного быстрее, гарантируя, что сначала проверяются наиболее распространенные случаи: Если x равен нулю 90% времени, код » if-else может быть в два раза быстрее, чем switch-based код. Даже если компилятор превратит «коммутатор» в какой-то умный настольный goto, он все равно не будет таким быстрым, как просто проверка на ноль. Итак, если if / else выглядит лучше, используйте его, иначе используйте оператор switch. боковая тема, но я часто беспокоюсь (и чаще вижу) if / else и switch заявление слишком большие слишком многих случаях. Они часто вредят ремонтопригодности. общие виновники включают в себя: вы можете выполнить процедуру or в коммутаторе Это фактически не отвечает на ваш вопрос, но, учитывая, что между скомпилированными версиями будет небольшая разница, я бы настоятельно рекомендовал вам написать свой код таким образом, чтобы лучше всего описать ваши намерения. Мало того, что у компилятора больше шансов сделать то, что вы ожидаете, но это облегчит другим поддерживать ваш код. Если ваше намерение состоит в том, чтобы ветвить вашу программу на основе значения одной переменной / атрибута, то оператор switch лучше всего представляет это намерение. Если ваше намерение состоит в том, чтобы ветвить вашу программу на основе различных переменных / атрибутов/условий, то if / else if chain лучше всего представляет это намерение. оператор switch определенно быстрее, чем if else if. Есть speedtest, которые были поставлены на нем BlackWasp но в значительной степени зависит от возможностей, которые вы пытаетесь объяснить, но я стараюсь использовать оператор switch, когда это возможно. не только C#, но и все языки на основе C, я думаю: поскольку коммутатор ограничен константами, можно создать очень эффективный код, используя «таблицу переходов». Случай C действительно является хорошим старым FORTRAN вычисленным GOTO, но случай C# по-прежнему проверяет константу. это не тот случай, когда оптимизатор сможет сделать тот же код. Рассмотрим, например, поскольку это составные логические значения, сгенерированный код должен вычислить значение и короткое замыкание. Теперь рассмотрим эквивалент Это может быть скомпилированы в потому что вы неявно говорите компилятору, что ему не нужно вычислять тесты OR и equality. Это то, что мы обнаружили: Допустимый оператор switch для чего-либо, кроме строки, компилируется в IL как оператор switch. Однако, если это строка, она переписывается как if/else if / else в IL. Поэтому в нашем случае мы хотели знать, как операторы switch сравнивают строки e.g чувствителен к регистру так далее. и рефлектор быстро дал нам ответ. Это было полезно знать. Если вы хотите сделать чувствительны к регистру сравнение строк, то вы мог бы используйте оператор switch, поскольку он быстрее, чем выполнение строки.Сравните в if / else. (Edit: Читать что быстрее, включить строку или elseif по типу? для некоторых фактических тестов производительности) однако, если вы хотите сделать регистр нечувствительным, то лучше использовать if / else в качестве результирующего кода не очень. лучшее эмпирическое правило-использовать операторы switch, если это имеет смысл (серьезно), e.g: обновление: небольшое примечание: для улучшения читаемости инструкций попробовать следующий: согласно этой ссылке,IF vs Switch сравнение итерационного теста с использованием switch и if statement, похоже на 1,000,000,000 итераций, время, затраченное переключатель утверждение= 43.0 s & by Если Заявление = 48.0 s — буквально 20833333 итерации в секунду, поэтому, если нам действительно нужно больше сосредоточиться, P. S:как раз знать разницу в представления для малого списка условия. мой профессор cs предложил вам не переключать заявления, так как так часто люди забывают перерыв или используют его неправильно. Я не могу точно вспомнить, что он сказал, но что-то вроде того, что, глядя на некоторую семенную кодовую базу, которая показывала примеры оператора switch (годы назад), также было много ошибок. Я Думаю, Что Переключатель Быстрее, Чем Если Условия как узнать, есть ли такая программа, как : напишите программу для ввода любого числа (между 1-99) и проверьте, в каком слоте a) 1 – 9 затем слот один b) 11 – 19 затем слот два c) 21-29 затем слот три и так далее до 89-99 затем, если вам нужно сделать много условий, но случай переключения сына, вы должны просто ввести и в случае 0 = 1-9, случай 1 = 11-19 и так далее Это будет так просто Есть Еще Много Таких Примеров! оператор switch в основном является сравнением для равенства. событие клавиатуры имеет большое преимущество перед оператором switch, когда легко писать и читать код, тогда оператор if elseif, пропуская <скобку>, также может вызвать беспокойство. оператор if elseif отлично подходит для более чем одного решения, если (theAmountOfApples больше, чем 5 & & theAmountOfApples меньше, чем 10) сохраните ваши яблоки еще если(theAmountOfApples превышает 10 || theAmountOfApples == 100) продайте свои яблоки. Я не пишу c# или C++, но я изучил его, прежде чем я узнал java, и они близкие языки. Я знаю, что это не совсем вопрос, но мне действительно нужно указать, что когда вы думаете об эффективности на этом уровне, вам может понадобиться больше абстракции в вашем коде. Вам больше не понадобятся переключатели, особенно если они содержат логику. (мой пример в php). теперь посмотрите на избыточность аналогичного кода! одним из возможных недостатков операторов switch является отсутствие нескольких условий. У вас может быть несколько условий для операторов if (else), но не несколько cases с разными условиями в коммутаторе. операторы Switch не подходят для логических операций за пределами простых булевых уравнений / выражений. Для этих булевых уравнений / выражений он в высшей степени подходит, но не для других логических операций. У вас гораздо больше свободы с логика, доступная в операторах If, но читаемость может пострадать, если оператор If становится громоздким или плохо обрабатывается. оба имеют место в зависимости от контекста того, с чем вы столкнулись. беспокоясь о производительности моего веб-приложения, мне интересно, какой из операторов» if/else » или switch лучше в отношении производительности? это микро-оптимизация и преждевременная оптимизация, которые являются злом. А беспокоиться о readabililty и ремонтопригодность код в вопрос. Если их больше двух if/else блоки склеены вместе или его размер непредсказуем, то вы можете высоко рассмотреть switch заявление. кроме того, вы также можете захватить полиморфизм. Сначала создайте некоторый интерфейс: наконец-то заменить if/else или switch чем-то вроде этого (оставляя в стороне тривиальные проверки, такие как nullpointers): поскольку вы говорите о веб-приложениях, вы можете использовать HttpServletRequest#getPathInfo() как ключ действия (в конечном итоге напишите еще немного кода для разделите последнюю часть pathinfo в цикле, пока не будет найдено действие). Вы можете найти здесь похожие ответы: если вы беспокоитесь о производительности Java EE webapplication в целом, то вы можете найти в этой статье полезен. Есть и другие области, которые дают больше увеличение производительности, чем только (микро)оптимизация исходного кода Java. Я полностью согласен с мнением, что преждевременной оптимизации следует избегать. но это правда, что Java VM имеет специальные байт-коды, которые могут быть использованы для switch (). таким образом, может быть некоторое повышение производительности, если код является частью графика производительности процессора. крайне маловероятно, что if/else или коммутатор станет источником ваших проблем с производительностью. Если у вас возникли проблемы с производительностью, сначала необходимо выполнить анализ профилирования производительности, чтобы определить, где находятся медленные пятна. Преждевременная оптимизация-корень всех зол! если этот набор не очень плотный, но n >= β, двоичное дерево поиска может найти цель в O(2 * log(n)), которая также эффективна. для всех других случаев оператор switch точно так же эффективен, как эквивалентная серия операторов if/else. Точные значения α и β зависят от ряда факторов и определяются модулем оптимизации кода компилятора. используйте переключатель! Я ненавижу поддерживать if-else-блоки! Тест: Я помню, что читал, что в байт-коде Java есть 2 вида операторов Switch. (Я думаю, что это было в «настройке производительности Java», это очень быстрая реализация, которая использует целочисленные значения оператора switch, чтобы знать смещение кода, который будет выполнен. Это потребует, чтобы все целые числа были последовательными и в четко определенном диапазоне. Я предполагаю, что использование всех значений перечисления также попадет в эту категорию. Я согласен со многими другими плакатами. может быть преждевременно беспокоиться об этом, если это не очень-очень горячий код. согласно Клифф клик в его 2009 Java One talk ускоренный курс современного оборудования: сегодня в производительности преобладают шаблоны доступа к памяти. Cache misses dominate-память-это новый диск. [Слайд 65] вы можете получить его полный скольжения здесь. Cliff дает пример (заканчивающийся на слайде 30), показывающий, что даже с процессором делает регистр-переименование, прогнозирование ветвей и спекулятивное выполнение, он может запускать только 7 операций за 4 такта, прежде чем блокировать из-за двух пропусков кэша, которые принимают 300 тактовые циклы для возврата. поэтому он говорит, чтобы ускорить вашу программу, вы не должны смотреть на такого рода незначительные проблемы, но на более крупных, таких как, делаете ли вы ненужные преобразования формата данных, такие как преобразование «SOAP → XML → DOM → SQL→. «, который «передает все данные через кэш». в моем тесте лучшая производительность ПЕРЕЧИСЛЕНИЕ > КАРТА > ПЕРЕКЛЮЧАТЕЛЬ > IF / ELSE IF в Windows7. для большинства switch и самого if-then-else блоки, я не могу себе представить, что есть какие-либо заметные или значительные проблемы, связанные с производительностью. но вот что: если вы используете switch block, само его использование предполагает, что вы включаете значение, взятое из набора констант, известных во время компиляции. В этом случае, вы действительно не должны использовать switch операторы вообще, если вы можете использовать enum С постоянн-специфическими методами. по сравнению с a switch оператор, перечисление обеспечивает лучшую безопасность типа и код, который легче поддерживать. Перечисления могут быть сконструированы таким образом, что если константа добавляется к набору констант, ваш код не будет компилироваться без предоставления метода константы для нового значения. С другой стороны, забыв добавить новый case до switch блок иногда может быть пойман только во время выполнения, если вам посчастливилось настроить свой блок для создания исключения. между switch и Ан enum constant-specific метод не должен существенно отличаться, но последний является более читаемым, безопасным и простым в обслуживании.
Может кто нибудь знает,какая конструкция лучше в плане производительности: 1) enum eЧто быстрее, вложенные REPLACE или функция с CASE на va?
Здравствуйте форумчане. Имеется база с приличным количеством записей, порядка миллиона. Задача в.Есть ли какая-либо существенная разница между использованием if/else и switch-case в C#?
по теме: что быстрее, включить строку или elseif по типу?
20 ответов
Вы не можете сделать:Какова относительная разница в производительности оператора if/else и switch в Java?
8 ответов