Сгенерированный код для switch-case
традиционно использует таблицу переходов. В этом случае прямой возврат через справочную таблицу представляется оптимизацией, использующей тот факт, что каждый случай здесь предполагает возврат. Хотя стандарт не дает никаких гарантий на этот счет, я был бы удивлен, если бы компилятор генерировал серию сравнений вместо таблицы переходов для обычного случая переключения.
Теперь перейдем к if-else
, это полная противоположность. В то время как switch-case
выполняется в постоянное время, независимо от количества ветвей, if-else
оптимизируется для меньшего количества ветвей. Здесь вы можете ожидать, что компилятор в основном сгенерирует серию сравнений в том порядке, в котором вы их написали.
Так что, если бы я использовал if-else
, потому что я ожидаю, что большинство вызовов square()
будут для 0
или 1
и редко для других значений, тогда «оптимизация» этого для поиска в таблице может фактически привести к тому, что мой код будет работать медленнее, чем я ожидаю, что лишит меня цели использовать if
вместо switch
. Таким образом, хотя это спорно, я чувствую G CC делает правильную вещь и лязг является чрезмерно агрессивным в его оптимизации.
1016 * Кто-то, в комментариях, поделился ссылкой, где лязг делает
это оптимизация и генерирует код на основе таблицы поиска для
if-else
. Что-то примечательное происходит, когда мы уменьшаем количество дел до двух (и по умолчанию) с помощью clang Он снова генерирует идентичный код для if и switch, но на этот раз
переключается на сравнение и перемещает вместо метода таблицы поиска, для обоих. Это означает, что даже одобряющий переключение клан знает, что шаблон «если» более оптимален, когда число случаев невелико!
В итоге, последовательность сравнений для if-else
и таблица переходов для switch-case
- это стандартный шаблон, которому, как правило, следуют компиляторы, и разработчики ожидают, когда они пишут код. Однако для некоторых особых случаев некоторые компиляторы могут отказаться от этого шаблона, если они считают, что он обеспечивает лучшую оптимизацию. Другие компиляторы могут в любом случае просто придерживаться шаблона, даже если он явно не оптимален, доверяя разработчику знать, чего он хочет. Оба являются действительными подходами со своими преимуществами и недостатками.