Загрузка...

суббота, 21 июня 2008 г.

Как отказаться от виртуальных функций в угоду производительности

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

Решение этой проблемы простое и лежит на поверхности — замена наследования шаблонами. Как это можно реализовать, смотрите здесь, я же отмечу, что в результате получается трехкратный прирост производительности. Немало для задач, критичных ко времени.

Метки Technorati: ,

6 коммент.:

dzhariy комментирует...

Тот пример с шаблонами достаточно прост для того, чтобы понять, насколько сложным код делает процесс оптимизации. По моему мнению, в более сложных проектах такой прием поставит на файл исходника атрибут write-only :)

allex комментирует...

Я сначала удивился - если правильно помню, виртуальные функции должны быть медленее не в три раза, а в полтора. А потом внимательно почитал сообщение по ссылке и успокоился - замер производительности не совсем корректен, потому что невиртуальные функции оказались inline.

sash_ko комментирует...

Про такой подход можно почитать в C++ Templates: The Complete Guide, называется Parameterized Virtuality. Реальные примеры, насколько я помню, это ATL, crypto++.

Alno комментирует...

1) Безусловно виртуальные функции несут дополнительные издержки. Однако, мне кажется, что говорить, будто бы отказ от них приводит к n-кратному увеличению производительности для любого n не совсем корректно, по той причине, что это число значительно зависит от используемой системы.

2) Предлагаемый подход, интересен, однако как минимум усложняет объявление класса b снижает читабельность/модифицируемость/сопровождаемость кода. Окромя этого, весь код плавно перетекает в заголовочные файлы, что еще и значительно увеличивает время компоновки.

3) Уменьшить накладные расходы от использования виртуальных функций, наверное, проще хорошо проектируя систему, учитывая издержки виртуальности.

Alno комментирует...

Кстати, переименуй пост, наверное))
Отказываемся мы все-таки всего лишь от виртуальных функций, а не от наследования.

Сергей | codeBlogZ комментирует...

Кстати, переименуй пост, наверное))
Отказываемся мы все-таки всего лишь от виртуальных функций, а не от наследования.

Действительно, мой ляпсус ;)

Все твои замечания верны, ведь у каждого подхода есть свои недостатки, которые покрываются преимуществами, уместные в конкретной ситуации. Где необходима высокая скорость реакции run-time, такой подход вполне оправдан. И даже не важно, во сколько раз мы получаем лучшую производительность. Главное, что оно очевидно. Остальное дело техники ;)

Отправить комментарий | Feed



 
^

Powered by BloggerCreative Commons License