4

我有两个派生类型(child1 和 child2),它们都从同一个抽象类型 ( type, abstract :: parent) 扩展而来。抽象类型有一个延迟绑定过程。

我想调用一个子程序来执行一些事情(性能关键),具体取决于作为输入移交的孩子的类型。我可以想到两个选择:

  • 子例程将class(parent), intent(inout) :: type_in输入作为输入。然后在select type (type_in)构造中完成子项的实现。
  • 我编写了两个子例程,一个 withtype(child1), intent(inout) :: type_in和一个 with,type(child2), intent(inout) :: type_in并提供了一个显式接口来重载例程名称。

第一个选项允许在编译时不知道父级扩展的实现,但在我的情况下这不是必需的。它还节省了一些代码行,因为只有一部分代码对孩子来说是不同的。

我的问题是:选项一中是否有额外的开销,因为我在编译时知道类型时将输入实现为多态数据?

4

1 回答 1

4

是的,所谓的虚拟通话会产生额外费用。使用虚拟方法表(在其他语言中调用它)并搜索要调用的正确过程。成本可能与 C++ 中的虚函数调用相似,请参阅https://stackoverflow.com/a/453001/721644

即使在编译时,编译器有时也能够找出绑定调用了哪个过程。例如,当实际传递的对象是非多态的。GCC 有两个标志-fdevirtualize-fdevirtualize-speculatively(使用 -O2、-O3、-Os 启用)将虚拟调用转换为直接调用。它们也可能适用于 Fortran。

于 2015-10-02T20:35:05.257 回答