Операторы Switch часто являются распространенным источником оптимизации компилятора.То есть то, как они обрабатываются, зависит от настроек оптимизации, которые вы используете в своем компиляторе.
Самый базовый (неоптимизированный) способ составления оператора switch - это трактовать его как цепочку операторов if ... else if ...
.,Обычный способ, которым компиляторы оптимизируют переключатель, - это преобразовать его в таблицу переходов , которая может выглядеть примерно так:
if (condition1) goto label1;
if (condition2) goto label2;
if (condition3) goto label3;
else goto default;
label1:
<<<code from first `case statement`>>>
goto end;
label2:
<<<code from first `case statement`>>>
goto end;
label3:
<<<code from first `case statement`>>>
goto end;
default:
<<<code from `default` case>>>
goto end;
end:
Одна из причин, по которой этот метод быстрее, состоит в том, что код внутри условных выраженийменьше (так что меньше штраф кеша инструкций, если условие неверно предсказано).Кроме того, «провальный» случай становится более тривиальным для реализации (компилятор пропускает оператор goto end
).
Компиляторы могут дополнительно оптимизировать таблицу переходов, создавая массив указателей (на отмеченные местоположенияпо меткам) и используйте значение, которое вы включаете в качестве индекса в этом массиве.Это исключило бы почти все условные выражения из кода (за исключением того, что было необходимо для проверки того, соответствует ли значение, которое вы включаете, одному из ваших случаев или нет).
Предупреждение: вложенные таблицы переходовтрудно сгенерировать, и некоторые компиляторы отказываются даже пытаться его создать.По этой причине избегайте вложения switch
в другой switch
, если для вас важен максимально оптимизированный код (я не уверен на 100%, как MSVC, в частности, обрабатывает вложенные switch
es, но руководство компилятора должно сказать вам,).