Влияние виртуального наследования на производительность - PullRequest
26 голосов
/ 04 февраля 2011

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

Ответы [ 3 ]

27 голосов
/ 04 февраля 2011

Обычные реализации предоставят доступ к членам данных виртуальных базовых классов с использованием дополнительной косвенной ссылки.

Как указывает Джеймс в своих комментариях, вызов функции-члена базового класса в сценарии множественного наследования потребует корректировки указателя this, и если этот базовый класс является виртуальным, то смещение подпрограммы базового класса -объект в объекте производного класса зависит от динамического типа производного класса и должен быть рассчитан во время выполнения.

Влияет ли это на производительность в реальных приложениях, зависит от многих факторов:

  • Есть ли у виртуальных баз элементы данных вообще? Зачастую это абстрактные базовые классы, которые должны быть получены из виртуальных источников, а абстрактные базы, в которых есть какие-либо элементы данных, часто так или иначе являются запахом кода.

  • Предполагая, что у вас есть виртуальные базы с элементами данных, к ним обращаются по критическому пути ? Если пользователь, нажимающий на какую-либо кнопку в графическом интерфейсе, приводит к нескольким десяткам дополнительных косвенных указаний, никто не заметит.

  • Какой будет альтернатива , если избежать виртуальных баз? Мало того, что дизайн может быть хуже, также вероятно, что альтернативный дизайн также оказывает влияние на производительность. Он должен достичь той же цели, ведь и TANSTAAFL. Затем вы обменяли одну потерю производительности на другую плюс худший дизайн.


Дополнительное примечание: взгляните на Стэна Липпмана внутри объектной модели C ++ , которая довольно подробно отвечает на такие вопросы.

3 голосов
/ 04 февраля 2011

Взгляните на следующее крупномасштабное экспериментальное исследование, опубликованное 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}
}

Аннотация: Изучаем прямую стоимость виртуальной функции вызовы в программах на C ++, при условии стандартного реализация с использованием таблиц виртуальных функций. Мы измерить эти накладные расходы экспериментально для ряда большие контрольные программы, использующие комбинацию проверка исполняемого файла и моделирование процессора. наш результаты показывают, что программы на C ++ измеряют тратить средний 5,2% своего времени и 3,7% своего инструкции в коде отправки. Для «всех виртуалов» версии программ, средняя нагрузка возрастает до 13,7% (13% инструкции). «Тук» вариант реализации таблицы виртуальных функций уменьшает накладные расходы в среднем на 21% относительно стандартная реализация. На будущих процессорах эти накладные расходы могут увеличиться умеренно

http://www.cs.ucsb.edu/~urs/oocsb/papers/oopsla96.pdf

0 голосов
/ 04 февраля 2011

Вы уверены, что имеете в виду виртуальное наследование? Если это так, это соответствует стоимости обычного вызова виртуальной функции. Поиск в цепочке vtable идет по указанному пути.

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

...