На современном процессоре многие из них сводятся к предсказанию ветвления. Хотя оператор switch может быть реализован как таблица перехода, которая занимает примерно один и тот же промежуток времени для выполнения любой ветви кода, она также в целом довольно непредсказуема - буквально; предсказатель ветвления часто будет выполнять довольно плохую работу по прогнозированию того, какая ветка будет принята, что означает, что есть очень хорошие шансы на пузырь трубопровода (обычно около 15 потраченных впустую циклов или около того).
Оператор if может делать больше сравнений, но большинство ветвей, вероятно, принимаются одинаково почти каждый раз, поэтому предсказатель ветвления может более точно предсказать их результаты.
Указатели на функции также могут быть непредсказуемыми. Хуже того, до недавнего времени большинство процессоров в значительной степени даже не пытались. Только довольно недавно добавили достаточно для большинства реализаций BTB (Branch Target Buffer), что они действительно могут даже сделать серьезную попытку предсказать цель ветки через указатель. На более старых процессорах указатели на функции часто довольно плохо сравниваются по скорости.
Возникли вопросы здесь? На минимальном уровне вам придется показывать код. Вы никак не можете измерить какую-либо разницу между этими тремя с ~ 20 случаями ... – 2010-02-19 02:16:48
Я могу подтвердить ваши результаты. Я также делал ставку на массив указателей, являющийся самым быстрым. Еще одна причина использовать профилировщик, прежде чем вы будете * любой * оптимизировать. – vava
Вы должны включить инициализацию времени выполнения вашего «массива указателей» в вашем тесте синхронизации. Это, и компилятор, вероятно, оптимизирует вызовы косвенных функций, потому что вы помещаете все в одну единицу перевода. Вы не можете убедить меня, что вы можете измерить разницу между ними с наивным испытанием 20 случаев! – 2010-02-19 02:44:48