4

同じ抽象型 ( ) から拡張された 2 つの派生型 (child1 と child2) がありtype, abstract :: parentます。抽象型には遅延バインド プロシージャがあります。

入力として渡された子のタイプに応じて、何らかの処理 (パフォーマンスが重要) を実行するサブルーチンを呼び出したいと考えています。次の 2 つのオプションが考えられます。

  • サブルーチンはclass(parent), intent(inout) :: type_inを入力として受け取ります。select type (type_in)子の実装は、コンストラクト内で行われます。
  • type(child1), intent(inout) :: type_in1 つは with で、もう1 つは with で、2 つのサブルーチンを作成しtype(child2), intent(inout) :: type_in、ルーチン名をオーバーロードするための明示的なインターフェイスを提供します。

最初のオプションは、コンパイル時に親の拡張が不明な実装を可能にしますが、私の場合は必要ありません。また、一部のコードのみが子と異なるため、コードの行数も節約できます。

私の質問は次のとおりです。コンパイル時にタイプがわかっている場合、入力をポリモーフィック データとして実装したため、オプション 1 に追加のオーバーヘッドがありますか?

4

1 に答える 1

4

はい、いわゆる仮想通話には追加料金がかかります。仮想メソッド テーブル (他の言語で呼び出される) が使用され、呼び出す正しいプロシージャが検索されます。コストは、C++ での仮想関数呼び出しのコストに似ている可能性があります。https://stackoverflow.com/a/453001/721644を参照してください。

コンパイラは、コンパイル時であっても、バインドによって呼び出されたプロシージャを見つけることができる場合があります。たとえば、実際に渡されたオブジェクトがポリモーフィックでない場合です。GCC には、仮想呼び出しを直接呼び出しに変換する 2 つのフラグ-fdevirtualize( -fdevirtualize-speculatively-O2、-O3、-Os で有効化) があります。Fortran にも適用できる可能性があります。

于 2015-10-02T20:35:05.257 に答える