Оператор переключения и отдельные вызовы функций для повышения производительности ⇐ C++
-
Гость
Оператор переключения и отдельные вызовы функций для повышения производительности
Я пишу виртуальную машину, и основной цикл выглядит примерно так:
во время (работает) { переключатель (get_opcode()) { случай 0x00: прерывание some_instruction(); ... } } Некоторые инструкции имеют аналогичную функцию, например: cast_32 и cast_64. Поэтому я подумал о двух вариантах:
[*]Создайте для каждого из них отдельную функцию.
// основной цикл виртуальной машины переключатель (get_opcode()) { случай X: прерывание some_instruction_version_x(); случай Y: some_instruction_version_y() перерыв; } ... // реализации инструкций аннулировать some_instruction_version_x() { // сделай что-нибудь } аннулировать some_instruction_version_y() { // делаем что-то немного другое } [*]Используйте ту же функцию, но с оператором переключения внутри нее. // основной цикл виртуальной машины переключатель (get_opcode()) { случай X: some_instruction(some_enum::X) перерыв; случай Y: some_instruction(some_enum::Y) перерыв; } ... // реализации инструкций void some_instruction (версия some_enum) { // делаем что-то общее для обеих версий переключатель (версия) { case some_enum::X: /* делаем x определенных действий */break; case some_enum::Y: /* делаем что-то конкретное */break; } } Хотя я думаю, что версия 2 выглядит «чище», я немного обеспокоен тем, что оператор переключения во втором варианте повлияет на производительность, учитывая, что это виртуальная машина, и этот код может выполняться очень часто.
Итак, мой вопрос: какой вариант лучше, и действительно ли оператор переключения в варианте 2 повлияет на производительность или компилятор, возможно, оптимизирует его и разделит на две функции сам?
Я пишу виртуальную машину, и основной цикл выглядит примерно так:
во время (работает) { переключатель (get_opcode()) { случай 0x00: прерывание some_instruction(); ... } } Некоторые инструкции имеют аналогичную функцию, например: cast_32 и cast_64. Поэтому я подумал о двух вариантах:
[*]Создайте для каждого из них отдельную функцию.
// основной цикл виртуальной машины переключатель (get_opcode()) { случай X: прерывание some_instruction_version_x(); случай Y: some_instruction_version_y() перерыв; } ... // реализации инструкций аннулировать some_instruction_version_x() { // сделай что-нибудь } аннулировать some_instruction_version_y() { // делаем что-то немного другое } [*]Используйте ту же функцию, но с оператором переключения внутри нее. // основной цикл виртуальной машины переключатель (get_opcode()) { случай X: some_instruction(some_enum::X) перерыв; случай Y: some_instruction(some_enum::Y) перерыв; } ... // реализации инструкций void some_instruction (версия some_enum) { // делаем что-то общее для обеих версий переключатель (версия) { case some_enum::X: /* делаем x определенных действий */break; case some_enum::Y: /* делаем что-то конкретное */break; } } Хотя я думаю, что версия 2 выглядит «чище», я немного обеспокоен тем, что оператор переключения во втором варианте повлияет на производительность, учитывая, что это виртуальная машина, и этот код может выполняться очень часто.
Итак, мой вопрос: какой вариант лучше, и действительно ли оператор переключения в варианте 2 повлияет на производительность или компилятор, возможно, оптимизирует его и разделит на две функции сам?
Мобильная версия