当类型在编译时已知时,是否有额外的开销调用具有多态派生类型的子例程?
Is there additional overhead calling subroutines with polymorphic derived types when the type is known at compile time?
我有两个派生类型(child1 和 child2),它们都从相同的抽象类型(type, abstract :: parent
)扩展而来。抽象类型具有延迟绑定过程。
我想调用一个子例程,该子例程根据作为输入移交的 child 类型执行某些操作(性能关键)。我可以想到两个选项:
- 子程序将
class(parent), intent(inout) :: type_in
作为输入。 children 的实现随后在 select type (type_in)
构造中完成。
- 我写了两个子例程,一个用
type(child1), intent(inout) :: type_in
,一个用 type(child2), intent(inout) :: type_in
,并提供一个显式接口来重载例程名称。
第一个选项允许在编译时不知道 parent 的扩展名的实现,但在我的情况下这不是必需的。它还节省了一些代码行,因为它只有一部分与 children.
不同
我的问题是:选项一是否有额外的开销,因为我在编译时类型已知时将输入实现为多态数据?
是的,so call 虚拟通话需要额外付费。使用虚方法 table(在其他语言中称为虚方法)并搜索要调用的正确过程。成本可能类似于 C++ 中的虚函数调用,请参阅
编译器有时甚至可以在编译时找出绑定调用了哪个过程。例如,当实际传递的对象是非多态时。 GCC 有两个标志 -fdevirtualize
和 -fdevirtualize-speculatively
(通过 -O2、-O3、-Os 启用)将虚拟调用转换为直接调用。它们也可能适用于 Fortran。
我有两个派生类型(child1 和 child2),它们都从相同的抽象类型(type, abstract :: parent
)扩展而来。抽象类型具有延迟绑定过程。
我想调用一个子例程,该子例程根据作为输入移交的 child 类型执行某些操作(性能关键)。我可以想到两个选项:
- 子程序将
class(parent), intent(inout) :: type_in
作为输入。 children 的实现随后在select type (type_in)
构造中完成。 - 我写了两个子例程,一个用
type(child1), intent(inout) :: type_in
,一个用type(child2), intent(inout) :: type_in
,并提供一个显式接口来重载例程名称。
第一个选项允许在编译时不知道 parent 的扩展名的实现,但在我的情况下这不是必需的。它还节省了一些代码行,因为它只有一部分与 children.
不同我的问题是:选项一是否有额外的开销,因为我在编译时类型已知时将输入实现为多态数据?
是的,so call 虚拟通话需要额外付费。使用虚方法 table(在其他语言中称为虚方法)并搜索要调用的正确过程。成本可能类似于 C++ 中的虚函数调用,请参阅
编译器有时甚至可以在编译时找出绑定调用了哪个过程。例如,当实际传递的对象是非多态时。 GCC 有两个标志 -fdevirtualize
和 -fdevirtualize-speculatively
(通过 -O2、-O3、-Os 启用)将虚拟调用转换为直接调用。它们也可能适用于 Fortran。