Я рассматриваю возможность использования виртуального наследования в приложении реального времени. Имеет ли использование виртуального наследования влияние производительности, аналогичное действию вызова виртуальной функции? Объекты, о которых идет речь, будут созданы только при запуске, но я обеспокоен тем, будут ли отправлены все функции из иерархии через vtable или если будут только те из виртуального базового класса.
Эффективное влияние виртуального наследования
Ответ 1
В рамках общих реализаций доступ к элементам данных виртуальных базовых классов использует дополнительную косвенность.
Как отмечает Джеймс в своих комментариях, вызов функции-члена базового класса в сценарии множественного наследования потребует корректировки указателя this
, и если этот базовый класс является виртуальным, то смещение базового класса sub -объект в объекте производного класса зависит от динамического типа производного класса и его необходимо будет вычислить во время выполнения.
Является ли это видимым воздействием на приложения реального мира, зависит от многих факторов:
-
У виртуальных баз есть элементы данных вообще? Часто это абстрактные базовые классы, которые должны быть получены из практически, а абстрактные базы, в которых есть какие-либо члены данных, часто являются запахами кода в любом случае.
-
Предполагая, что у вас есть виртуальные базы с элементами данных, доступны ли те, которые были доступны в критическом пути? Если пользователь, нажимая на какую-либо кнопку в графическом интерфейсе, получает несколько десятков дополнительных указаний, никто не заметит.
-
Каким будет альтернативный, если избежать виртуальных баз? Мало того, что дизайн может быть хуже, также вероятно, что альтернативный дизайн также влияет на производительность. В конце концов, он должен достичь той же цели и TANSTAAFL. Затем вы торгуете одной потерей производительности для другого плюс более низкий дизайн.
Дополнительная заметка: посмотрите на Стэн Липпманн Внутри объектной модели С++, который полностью отвечает на такие вопросы.
Ответ 2
Взгляните на следующее крупномасштабное экспериментальное исследование, опубликованное OOPSLA'96. Я копирую вставку записи bibtex, реферат и ссылку на бумагу. Я бы рассмотрел это наиболее полное экспериментальное исследование по этой теме на сегодняшний день.
@article{driesen1996direct,
title={{The direct cost of virtual function calls in C++}},
author={Driesen, K. and H{\\"o}lzle, U.},
journal={ACM Sigplan Notices},
volume={31},
number={10},
pages={306--323},
issn={0362-1340},
year={1996},
publisher={ACM}
}
Аннотация: Мы изучаем прямую стоимость виртуальной функции вызовы в программах на С++, предполагая, что стандарт с использованием таблиц виртуальных функций. Мы экспериментально измерить эти накладные расходы для ряда крупных эталонных программ, используя комбинацию исполняемый контроль и моделирование процессоров. наш результаты показывают, что программы на С++ измеряют медиана 5,2% от их времени и 3,7% их инструкции по отправке. Для "всех виртуальных" версии программ, средняя накладная 13,7% (13% от инструкций). Вариант "thunk" реализации виртуальной таблицы функций уменьшает накладные расходы медианной 21% по сравнению с стандартная реализация. В будущих процессорах эти накладные расходы, вероятно, увеличатся умеренно
Ответ 3
Вы уверены, что имеете в виду виртуальное наследование? Если это так, то он идентичен стоимости обычного вызова виртуальной функции. Поиск в виртуальной цепочке vtable следует по указанному пути.
Ты сказал, что это было при запуске. Накладные расходы на диск (от простой загрузки вашего кода в память), вероятно, потребуют на несколько порядков больше времени, чем полдюжины инструкций или около того для поиска vtable. Я был бы удивлен, если бы вы могли прокомментировать это и обнаружить разницу.