Я установил (возможно, очень ненаучный) небольшой тест, чтобы определить накладные расходы на виртуальные функции в одноуровневом одиночном наследовании, и полученные результаты были точно такими же, когда обращались к производному классом или при обращении к нему напрямую. Что было немного удивительно, так это порядок величины времени вычисления, который вводится, когда любая функция объявляется виртуальной (см. Результаты ниже).Проверка накладных расходов на виртуальные функции
Есть ли так много накладных расходов при объявлении функций-членов как таковых и почему они все еще присутствуют даже при непосредственном доступе к производному классу?
Код выглядит следующим образом:
class base
{
public:
virtual ~base() {}
virtual uint func(uint i) = 0;
};
class derived : public base
{
public:
~derived() {}
uint func(uint i) { return i * 2; }
};
uint j = 0;
ulong k = 0;
double l = 0;
ushort numIters = 10;
base* mybase = new derived; // or derived* myderived = ...
for(ushort i = 0; i < numIters; i++)
{
clock_t start2, finish2;
start2 = clock();
for (uint j = 0; j < 100000000; ++j)
k += mybase->func(j);
finish2 = clock();
l += (double) (finish2 - start2);
std::cout << "Total duration: " << (double) (finish2 - start2) << " ms." << std::endl;
}
std::cout << "Making sure the loop is not optimized to nothing: " << k << std::endl;
std::cout << "Average duration: " << l/numIters << " ms." << std::endl;
Результаты:
base* mybase = new derived;
дает в среднем ~ 338 мс.
derived* myderived = new derived;
дает среднее значение ~ 338 мс.
Устранение наследования и удаление виртуальных функций дает в среднем ~ 38 мс.
Это почти в 10 раз меньше! Итак, в принципе, если какая-либо функция объявлена виртуальной, накладные расходы всегда будут идентично присутствовать, даже если я не буду использовать ее полиморфно?
Спасибо.
Кажется, что вы вычисляете стоимость наследования + виртуальные функции вместе. Вы должны протестировать экземпляр производного класса без каких-либо виртуальных функций, а также базового класса. –
Зачем использовать 'new'? Было бы проще создать экземпляр объекта в стеке ... –
В этом случае это не имело бы никакого значения. Такие же накладные расходы при доступе через указатель. –