Ваш вопрос вызвал у меня любопытство, поэтому я выбрал тактирование для процессора PowerPC 3GHz, с которым мы работаем. Тест, который я выполнил, состоял в создании простого 4d векторного класса с функциями get / set
class TestVec
{
float x,y,z,w;
public:
float GetX() { return x; }
float SetX(float to) { return x=to; } // and so on for the other three
}
Затем я установил три массива, каждый из которых содержал 1024 этих вектора (достаточно малых, чтобы поместиться в L1), и провел цикл, который добавил их друг к другу (A.x = B.x + C.x) 1000 раз. Я запустил это с функциями, определенными как inline
, virtual
и обычными вызовами функций. Вот результаты:
- встроенный: 8 мс (0,65 нс на звонок)
- прямой: 68 мс (5,53 нс на звонок)
- виртуальный: 160 мс (13 нс на звонок)
Итак, в этом случае (когда все умещается в кеше) вызовы виртуальных функций были примерно в 20 раз медленнее, чем встроенные вызовы. Но что это на самом деле означает? Каждое отключение в цикле вызывало ровно 3 * 4 * 1024 = 12,288
вызовов функций (1024 вектора, умноженные на четыре компонента, умноженные на три вызова на сложение), поэтому эти времена представляют 1000 * 12,288 = 12,288,000
вызовов функций. Виртуальный цикл занимал на 92 мс дольше, чем прямой цикл, поэтому дополнительные издержки на вызов составляли 7 наносекунд на функцию.
Из этого я делаю вывод: да , виртуальные функции намного медленнее, чем прямые функции, и нет , если только вы не планируете вызывать их десять миллионов раз в секунду, это не так. не имеет значения.
См. Также: сравнение сгенерированной сборки.