Множественное наследование, виртуальные функции и виртуальная таблица в C++

Я знаю, что поиск виртуальных функций в vtable намного медленнее, чем прямой вызов функций, поскольку базовый класс должен искать в vtable, чтобы получить производную функцию. Я бродил, было бы еще медленнее, если бы было больше производных слоев классов. В основном мой вопрос заключается в следующем:

Вызывает ли виртуальная функция Base -> Derived (1 уровень наследования) более быстрый вызов, чем вызов виртуальной функции Base -> Derived1 -> Derived2 -> Derived3 -> DerivedEtc (множественные уровни)?

1 ответ

Решение

Нет разницы в производительности поиска с одним косвенным путем, чтобы найти виртуальную функцию, которая будет вызываться в случае класса, полученного из двухуровневого наследования, а не из класса, наследуемого из 40 уровней.

Причина в следующем: каждый класс содержит указатель на виртуальную таблицу, которая используется для определения, какая функция должна быть вызвана для этого конкретного объекта:

class Base
{
public:
    virtual void function1() {};
    virtual void function2() {};
};

class D1: public Base
{
public:
    virtual void function1() {};
};

class D2: public Base
{
public:
    virtual void function2() {};
};

Приведенный выше код генерирует три виртуальные таблицы: одну для объектов класса Baseодин для предметов класса D1 и один для объектов класса D2,

Важным моментом здесь является то, что вам не нужно проходить все виртуальные таблицы с нуля, чтобы найти, какую функцию вызывать для конкретного объекта:

введите описание изображения здесь

на диаграмме выше вы просто

  1. Следовать vptr для вашего объекта (одно направление)
  2. Назовите адрес интересующей вас функции

Современные компиляторы могут оптимизировать этот процесс в двух пунктах, которые я перечислил выше, и, за исключением некоторых особых случаев, это не окажет заметного влияния на производительность.

Кредиты: http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/


Дополнительно: как отметил dyp, "медленное выполнение" виртуальных функций обычно относится к тому факту, что эти функции не могут быть встроены из-за косвенной зависимости vtable. Независимо от того, имеет ли это значение или нет, все сводится к коду и архитектуре, с которой вы работаете (например, давление регистра и другие факторы).

Другие вопросы по тегам