что быстрее if или switch java
Эстетическая красота: 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 и switch в Java?
беспокоясь о производительности моего веб-приложения, мне интересно, какой из операторов» if/else » или switch лучше в отношении производительности?
8 ответов
это микро-оптимизация и преждевременная оптимизация, которые являются злом. А беспокоиться о 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 метод не должен существенно отличаться, но последний является более читаемым, безопасным и простым в обслуживании.
Взаимозаменяем ли switch с if в JavaScript?
Оценить 3 комментария
Ситуация, в которой есть смысл сравнивать эти инструкции — проверка на соответствие множеству взаимоисключающих условий.
if else
Обрабатываются все условия методично, друг за другом.
switch
Каждый case — точка входа в блок инструкций.
Если сравнивать быстродействие, то webkit покажет почти одинаковые результаты, в Gecko производительность выше у switch, но не кардинально (на 20-30%), что не принципиально.
А вот логика у этих инструкций разная. Это заметно, если для некоторых значений требуется выполнить одни и те же инструкции. В этом случае написанные подряд case могут быть удобней, чем составная проверка в if. Кроме того, после выполнения входа выполнение инструкций продолжается либо до инструкции break, либо до окончания инструкции switch. И тут у switch появляются дополнительные возможности.
Следует также учесть, что в инструкции switch выполняется проверка с учётом типа (===), что отличает её от if, в которой проверяться может хоть приведённое значение (==), хоть чёрт в ступе. Значения case должны представлять собой примитивы (выражения, в результате выполнения которых подставляются примитивы).
А вот такое возможно только с использованием switch
Java: If vs. Switch
Some of the answers below regard alternative approaches to the approach above.
I have included the following to provide context for its use.
The reason I asked, the Question above, was because the speed of adding words empirically improved.
This isn’t production code by any means, and was hacked together quickly as a PoC.
11 Answers 11
Don’t worry about performance; use the syntax that best expresses what you’re doing. Only after you have (a) demonstrated a performance deficiency; and (b) localized it to the routine in question, only then should you worry about performance. For my money, the case syntax is more appropriate here.
However, heavily used code is typically compiled in any sensible JVM. The optimiser is not entirely stupid. Don’t worry about it, and follow the usual heuristics for optimisation.
It looks like you have enumerated the values so perhaps an enumeration is in order?
Also, there is a possible bug in your code where «A» == «A» may be false depending on the object identity of the «A»‘s.
Not quite an answer to your question, but there’s actually a bug in your code, you should have a break after each case:
I don’t think performance differences are going to be too significant here, but if you really care about performance, and if this code is executed very frequently, here’s another option:
Be sure to encapsulate this and document it well though.
Honestly, I don’t think the performance matters in this case. It’s really up to the compiler and its optimization.
If you have a switch statement with consecutive, integral values, depending on the language, it may be optimized to a branch table, which is very quick. It’s not slower, anyway!
Additionally, using if/else if would be an improvement over if, for cases such as this one in which your cases are mutually exclusive. No sense making 25 more checks after matching A.
But basically, any performance difference is negligible, and you ought to use the most correct syntax, which in this case is the switch statement. Make sure to separate your cases with breaks though.
Here’s a way to avoid all of the case statements.
I know this is not what you are asking at all, but aren’t you just doing this?
Are you simply looking for something a little more memory efficient?
The switch statement should use a hash to select which case to go to. From there, every subsequent case will also be run if there are no break statements. For example, with your code, if you switch on X, it will immediately go to X, then Y, then Z. See the Java Tutorial.
Является ли» else if «быстрее, чем»switch() case»? [дубликат]
Я бывший парень Паскаль, в настоящее время изучаю C#. Мой вопрос заключается в следующем:
— Это код ниже быстрее, чем сделать переключатель?
какой из них быстрее?
Я спрашиваю, потому что моя программа имеет подобную структуру (много, много утверждений «еще если»). Должен ли я превратить их в переключатели?
14 ответов:
для всего нескольких элементов разница невелика. Если у вас есть много предметов, вы обязательно должны использовать переключатель.
Если коммутатор содержит более пяти элементов, он реализуется с помощью таблицы подстановки или хэш-списка. Это означает, что все элементы получают одинаковое время доступа по сравнению со списком if:s, где последний элемент занимает гораздо больше времени, поскольку он должен сначала оценить каждое предыдущее условие.
99,99% времени, вы не должны заботиться.
эти виды микрооптимизации вряд ли повлияют на производительность вашего кода.
кроме того, если вам нужно было заботиться, то вы должны делать профилирование производительности на вашем коде. В этом случае выяснение разницы в производительности между корпусом коммутатора и блоком if-else было бы тривиальным.
Edit: для ясности: реализовать любой дизайн понятнее и более ремонтопригодны. Обычно при столкновении с огромным переключателем или блоком if-else решение заключается в использовании полиморфизма. Найдите поведение, которое изменяется, и инкапсулируйте его. Мне приходилось иметь дело с огромным, уродливым кодом switch case, как это раньше, и, как правило, это не так сложно упростить. Но о, так приятно.
результаты показывают, что оператор switch выполняется быстрее, чем лестница if-else-if. Это связано с возможностью компилятора оптимизировать оператор switch. В случае лестницы if-else-if код должен обрабатывать каждый оператор if в порядке, определенном программистом. Однако, поскольку каждый случай в операторе switch не полагаясь на более ранние случаи, компилятор может переупорядочить тестирование таким образом, чтобы обеспечить самое быстрое выполнение.
еще одна вещь, чтобы рассмотреть: это действительно узкое место вашего приложения? Бывают крайне редкие случаи, когда оптимизация такого рода действительно требуется. Большую часть времени вы можете получить намного лучшие ускорения, переосмыслив свои алгоритмы и структуры данных.
Я бы сказал, что переключатель-это путь, он быстрее и лучше практикуется.
существуют различные ссылки, такие как (http://www.blackwasp.co.uk/SpeedTestIfElseSwitch.aspx), которые показывают тестовые тесты, сравнивающие эти два.
не должно быть трудно проверить, создать функцию, которая переключается или ifelse между 5 числами, бросить rand (1,5) в эту функцию и цикл, что несколько раз во время синхронизации его.
переключатель находится, как правило, быстрее, чем длинный список «Если», потому что компилятор может генерировать таблицы переходов. Чем длиннее список, тем лучше операторе switch серии операторов if.
гораздо более важными, чем преимущества производительности коммутатора (которые относительно невелики, но стоит отметить) являются проблемы читаемости.
Я для одного нахожу оператор switch чрезвычайно ясным в намерениях и чистых пробелах, по сравнению с цепочками ifs.
Я не уверен, но я считаю, что скорость одной или другой меняется в зависимости от языка программирования, который вы используете.
Я обычно предпочитаю использовать переключатель. Таким образом, код является простым для чтения.
технически, они дают точно такой же результат, поэтому они должны быть оптимизируемы в значительной степени таким же образом. Однако есть больше шансов, что компилятор оптимизирует случай коммутатора с таблицей переходов, чем ifs.
Я говорю об общем случае. Для 5 записей среднее число тестов, выполненных для ifs, должно быть меньше 2,5, если вы заказываете условия по частоте. Вряд ли узкое место, чтобы написать домой, если только в очень плотном петля.
switch обычно переводится в таблицу поиска компилятором, если это возможно. Таким образом, поиск произвольного случая-Это O(1), вместо того, чтобы фактически делать несколько сравнений случаев, прежде чем найти тот, который вы хотите.
Так что во многих случаях if / else if цепи будет медленнее. Однако в зависимости от частоты, с которой ваши случаи поражаются, это может не иметь никакого значения.
короткий ответ: оператор Switch быстрее
оператор if вам нужно два сравнения (при запуске кода примера) в среднем, чтобы добраться до правильного предложения.
оператор switch среднее число сравнений будет одним независимо от того, сколько разных случаев у вас есть. Компилятор / виртуальная машина сделает «таблицу поиска» возможных параметров во время компиляции.
могут ли виртуальные машины оптимизировать оператор if аналогичным образом при запуске этот код часто?