2011-08-26 10 views
7

ちょっと前に、C++のdynamic_castの非常にきれいなパフォーマンスのアップグレードに関する非常に興味深い論文を見つけました:http://www2.research.att.com/~bs/fast_dynamic_casting.pdf高速ダイナミックキャスティングの進捗

基本的には、C++でdynamic_castを従来の継承ツリーの研究よりも高速にしています。論文に記載されているように、この方法は、高速で一定時間の動的鋳造アルゴリズムを提供する。

このホワイトペーパーは2005年に出版されました。現在、この技術はどこかに実装されているのか、どこに実装する予定があるのだろうかと思います。

+1

コンパイラがそれを使用しているかどうかはわかりませんが、ライブラリベースのRTTIソリューションをいくつか使用しています。 –

+0

「タイプID」の「割り当て」はリンク時に行われるため(ペーパーを参照)、ライブラリはどのようにそれを達成できますか?例がありますか? –

+0

全く同じではありません。 IDは他の方法で割り当てられますが、有効なキャストを決定するためにはモジュロを使用します。 –

答えて

7

さまざまなコンパイラがGCC(これは線形ではありません)の横にどのような実装を使用しているのか分かりません。しかし、紙が必ずしもすべての(または共通の)使用のための既存の実装より常に速い方法を提案するとは限らないことを強調することが重要です。継承階層が成長するにつれて漸近的に優れた一般的な解を提案する。

しかし、大きな継承階層を持つことは、アプリケーションをモノリシックにして柔軟に変更できなくなる傾向があります。柔軟な設計のプログラムは、主に2つのレベルの階層、抽象的な基盤、およびオープン/クローズド・プリンシプルをサポートする実行時ポリモーフィック・ロールの実装のみを持つ傾向があります。これらのケースでは、継承グラフを歩くことは、単一のポインタ逆参照および比較と同じくらい簡単であり、GibbsおよびStroustrupによって提示された索引 - 合計 - 逆参照 - 比較よりも速くなり得る。

また、独自のビジネスルールが必要としない限り、dynamic_castを使用するプログラムを作成するには、決してが必要であることを強調することが重要です。 dynamic_castの使用は、常に多型が適切に使用されておらず、再利用が危険にさらされていることを示しています。階層をキャストすることに基づいた動作が必要な場合は、仮想メソッドを追加するとクリーンなソリューションが得られます。タイプのdynamic_cast-checkを行うコードセクションがある場合、そのコードセクションは決して(オープン/クローズドプリンシプルの意味で)「閉じる」ことはなく、システムに追加されるすべての新しいタイプに対して更新する必要があります。一方、仮想ディスパッチは、新しいタイプでのみ追加され、展開を開いたままにして、基本タイプで動作するビヘイビアを閉じることができます。

これは実際には良い設計に従えば実際の世界の効果を持たないはずの学問的な提案です(マップをアルゴリズム的にhash_mapに変更することに相当します)。ビジネスルールが良い設計を禁じている場合(既存のアーキテクチャを変更したり、サードパーティのライブラリで一般的に使用されるようにアダプタを構築することができないコード障壁やコード所有権の問題があるショップもあります)どのアルゴリズムが実装されているかに基づいて、使用するコンパイラを決めるのは最善ではありません。常にパフォーマンスが重要で、dynamic_castなどの機能を使用する必要がある場合は、コードをプロファイルします。ツリーウォーキングの実装は実際にはより高速である可能性があります(多くの場合そうかもしれません)。

the standards committee's review of implementations, including dynamic_castおよびa well-known look at c++ in embedded environments and good use (which mentions Gibbs and Stroustrup in passing)も参照してください。

+0

私はdynamic_castのすべてでファンではありませんが、(通常はサードパーティのlibの使用や言語の "ハック"のために)必要な状況があります。 dynamic_castが悪いデザインの兆候であり、同じ振る舞いが別の方法で行われている可能性があることは初めてのことではありませんが、私はその声明または少なくともいくつかのポインタの "証明"を持っていたいと思います... –

+0

動的キャストは、条件付き実行のための変換可能なタイプと分岐ポイントへのアクセスを提供します。標準の証明は、仮想ディスパッチが同じ機能を提供することを示しているので、仮想関数内のビヘイビアを単純に実装することによって、 "if(dynamic_cast <...>(...))"コールを仮想ディスパッチに変換できます。拡張された証拠は、通常、第三者のライブラリが、意図された振る舞いで、階層のラッパークラスを提供することによって同様に使用できることを指摘しています。この変換は、実装へのアクセスが必要ないことを示しています。 – ex0du5