Виртуальные методы замедляют работу приложения, но могут ли они ускорить связывание? - PullRequest
0 голосов
/ 24 июня 2010

Как описано в Виртуальные функции и производительность - C ++ виртуальные методы могут влиять на производительность (дополнительный поиск в vtable, без вставки, ...).

Но мне было интересно, может ли использование виртуальных функций ускорить процесс связывания?

Предположим, у меня есть класс X, вызывающий метод класса Y.

  • Если метод не виртуальный, то
    • компилятор должен найти метод в классе Y, чтобы определить, является ли он допустимым и как переводить вызов в сборку
    • компоновщик должен найти метод в классе Y и заменить адрес вызова в сгенерированной компилятором сборке адресом вызываемого метода.
  • Если метод является виртуальным, то
    • компилятору также придется искать метод в классе Y и искать виртуальную таблицу класса Y для построения вызова (используя смещение в виртуальной таблице)
    • компоновщик больше ничего не должен делать

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

Это правда? У кого-нибудь есть опыт с этим? Было ли это когда-либо проверено?

Ответы [ 6 ]

3 голосов
/ 24 июня 2010

Дизайн вашего программного обеспечения должен зависеть не от скорости компиляции или компоновки, а от здравого смысла и уместности!

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

1 голос
/ 24 июня 2010

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

Во всяком случае, виртуальные вызовы замедляют время компиляции.

0 голосов
/ 25 июня 2010

Вы забываете, что компоновщик должен поместить адреса функций в vtables, а vtables в исполняемый файл.

0 голосов
/ 24 июня 2010

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

0 голосов
/ 24 июня 2010

Теоретически, компоновщик не должен делать так много для вызова виртуальной функции. Однако я склонен сомневаться, окажет ли это большое влияние на практике. Подумайте, какую работу должен выполнить компоновщик, чтобы избавиться от всего кода, на который нет ссылок (который, как правило, довольно велик в C ++).

Если время компоновки действительно является проблемой, ваши усилия могут быть лучше потрачены, например, на создание библиотек DLL / общих библиотек вместо статически связанного кода.

0 голосов
/ 24 июня 2010

Нет. Кроме того, не делайте этого по указанным вами причинам.

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

...