Известно, что использование виртуальных функций несет за собой несколько побочных эффектов — увеличивается размер класса за счет таблицы vtable, увеличивается время вызова виртуальных функций. При работе, например, с GUI-библиотекой эти недостатки не существенны. Однако, при проектировании классов, участвующих в активных вычислениях, это может привести к неоправданным издержкам.
Решение этой проблемы простое и лежит на поверхности — замена наследования шаблонами. Как это можно реализовать, смотрите здесь, я же отмечу, что в результате получается трехкратный прирост производительности. Немало для задач, критичных ко времени.
Метки Technorati: с++, improvements
Решение этой проблемы простое и лежит на поверхности — замена наследования шаблонами. Как это можно реализовать, смотрите здесь, я же отмечу, что в результате получается трехкратный прирост производительности. Немало для задач, критичных ко времени.
Метки Technorati: с++, improvements


6 коммент.:
Тот пример с шаблонами достаточно прост для того, чтобы понять, насколько сложным код делает процесс оптимизации. По моему мнению, в более сложных проектах такой прием поставит на файл исходника атрибут write-only :)
Я сначала удивился - если правильно помню, виртуальные функции должны быть медленее не в три раза, а в полтора. А потом внимательно почитал сообщение по ссылке и успокоился - замер производительности не совсем корректен, потому что невиртуальные функции оказались inline.
Про такой подход можно почитать в C++ Templates: The Complete Guide, называется Parameterized Virtuality. Реальные примеры, насколько я помню, это ATL, crypto++.
1) Безусловно виртуальные функции несут дополнительные издержки. Однако, мне кажется, что говорить, будто бы отказ от них приводит к n-кратному увеличению производительности для любого n не совсем корректно, по той причине, что это число значительно зависит от используемой системы.
2) Предлагаемый подход, интересен, однако как минимум усложняет объявление класса b снижает читабельность/модифицируемость/сопровождаемость кода. Окромя этого, весь код плавно перетекает в заголовочные файлы, что еще и значительно увеличивает время компоновки.
3) Уменьшить накладные расходы от использования виртуальных функций, наверное, проще хорошо проектируя систему, учитывая издержки виртуальности.
Кстати, переименуй пост, наверное))
Отказываемся мы все-таки всего лишь от виртуальных функций, а не от наследования.
Кстати, переименуй пост, наверное))
Отказываемся мы все-таки всего лишь от виртуальных функций, а не от наследования.
Действительно, мой ляпсус ;)
Все твои замечания верны, ведь у каждого подхода есть свои недостатки, которые покрываются преимуществами, уместные в конкретной ситуации. Где необходима высокая скорость реакции run-time, такой подход вполне оправдан. И даже не важно, во сколько раз мы получаем лучшую производительность. Главное, что оно очевидно. Остальное дело техники ;)