Я собираюсь ответить конкретно на ракурс производительности, потому что я работаю в критически важной среде, и некоторое время назад мне довелось провести измерения в аналогичном случае, чтобы найти самое быстрое решение.
Если вы используете процессор x86, PPC или ARM, вам нужны виртуальные функции в этой ситуации.Затраты на производительность при вызове виртуальной функции в основном составляют конвейерный пузырь , вызванный неправильным предсказанием косвенной ветви .Поскольку этап извлечения инструкций ЦП не может знать, куда идет вычисленный jmp, он не может начать выборку байтов с целевого адреса до тех пор, пока не выполнится ветвь, и, таким образом, в конвейере есть остановка, соответствующая числу этапов междуПервый этап извлечения и отделение удаляются.(На PPC я знаю лучше, это что-то вроде 25 циклов.)
У вас также есть задержка загрузки указателя vtable, но это часто скрывается переупорядочением команд (компилятор перемещает инструкцию load
так,он запускается за несколько циклов, прежде чем вам действительно понадобится результат, и ЦП выполняет другую работу, пока кеш данных отправляет вам свои электроны.прямых условных переходов - когда цель известна во время компиляции, но выполняется ли переход во время выполнения.(т. е. код операции jump-on-equal .) В этом случае ЦП будет делать предположение (прогнозировать), взята ли каждая ветвь или нет, и начнет получать инструкции соответствующим образом.Таким образом, у вас будет только пузырь, если процессор угадает неправильно.Поскольку вы, вероятно, каждый раз вызываете эту функцию с разными входными данными, она будет неправильно предсказывать хотя бы одну из этих ветвей, и вы получите точно такой же пузырь, как и с виртуальными.На самом деле, у вас будет гораздо больше пузырьков - по одному на условие if ()!
В виртуальных функциях также существует риск потери дополнительного кэша данных при загрузке виртуальной таблицы и ошибки icache нацель прыжка.Если эта функция находится в узком цикле, то, вероятно, вы будете много искать и вызывать одни и те же подпрограммы, и, таким образом, тела vtable и function, вероятно, все еще будут в кеше. Вы можете измерить это , если хотите быть действительно уверенным.