Быстрый динамический прогресс - PullRequest
8 голосов
/ 26 августа 2011

Некоторое время назад я обнаружил очень интересную статью об очень аккуратном обновлении производительности для dynamic_cast в C ++: http://www2.research.att.com/~bs/fast_dynamic_casting.pdf.

По сути, он делает dynamic_cast в C ++ намного быстрее, чем традиционные исследования дерева наследования. Как указано в статье, метод предусматривает быстрый алгоритм динамического приведения в постоянное время.

Эта статья была опубликована в 2005 году. Теперь мне интересно, применялась ли когда-нибудь эта методика или есть планы ее реализации где-либо?

1 Ответ

8 голосов
/ 27 августа 2011

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

Однако редко бывает целесообразно иметь большие иерархии наследования, поскольку они стремятся заставить приложение стать монолитным и негибким для изменения.Программы с гибким дизайном, как правило, имеют только иерархии, в основном с 2 уровнями, абстрактной базой и реализацией полиморфных ролей во время выполнения для поддержки открытого / закрытого принципа.В этих случаях обход графика наследования может быть таким же простым, как разыменование и сравнение одного указателя, что может быть быстрее, чем индекс-сумма-затем-разымещение-затем-сравнение, представленный Гиббсом и Страуструпом.

ТакжеВажно подчеркнуть, что никогда не требуется для написания программы, которая использует dynamic_cast, если только это не требуется вашим собственным бизнес-правилам.Использование dynamic_cast всегда указывает на то, что полиморфизм не используется должным образом и повторное использование ставится под угрозу.Если вам нужно поведение, основанное на приведении иерархии, добавление виртуального метода дает чистое решение.Если у вас есть секция кода, которая выполняет динамические проверки на типы, эта секция кода никогда не будет «закрыта» (в смысле открытого / закрытого принципа) и должна будет обновляться для каждого нового типа, добавляемого в систему.Виртуальная диспетчеризация, с другой стороны, добавляется только для новых типов, что позволяет вам оставаться открытым для расширения и в то же время закрывать поведение, работающее с базовым типом.

Так что это действительно довольно академическое предложение (приравниваниек изменению карты на hash_map алгоритмически), которая не должна иметь реальных эффектов, если следовать хорошему дизайну.Если бизнес-правила запрещают хороший дизайн (в некоторых магазинах могут быть барьеры кода или проблемы с владением кодом, когда вы не можете изменить существующие архитектуры такими, какими они должны быть, или они не позволяют создавать адаптеры, как это обычно используется для сторонних библиотек), тогдаЛучше не принимать решение о том, какой компилятор использовать, основываясь на том, какой алгоритм реализован.Как всегда, если производительность является ключевым фактором, и вы должны использовать такую ​​функцию, как dynamic_cast, профилируйте свой код.Возможно (и, вероятно, во многих случаях), что реализация обхода деревьев быстрее на практике.

См. Также обзор реализаций комитетом по стандартам, включая dynamic_cast и колодецизвестный взгляд на c ++ во встроенных средах и хорошее применение (мимоходом упоминается о Гиббсе и Страуструпе) .

...