Is there additional overhead calling subroutines with polymorphic derived types when the type is known at compile time?
I have two derived types (child1 and child2) that both extend from the same abstract type (type, abstract :: parent). The abstract type has a deferred bound procedure.
I want to call a subroutine that performs some stuff (performance critical) depending on the type of the child handed over as input. I can think of two options:
- The subroutine takes the class(parent), intent(inout) :: type_in as input. Implementations for the children are then done within a select type (type_in) construct.
- I write two subroutines, one with type(child1), intent(inout) :: type_in and one with type(child2), intent(inout) :: type_in and provide an explicit interface to overload the routine name.
The first option allows for implementations where the extension of the parent is not known at compile time, but that is not necessary in my case. It also saves some lines of code because only a part of it is different for the children.
My question is: Is there additional overhead in option one because I implemented the input as polymorphic data when the type is known at compile time?
Yes, there is additional cost of a so call virtual call. A virtual method table (as it is called in other languages) is used and searched for the right procedure to call. The cost is likely to be similar to that of a virtual function call in C++, see https://stackoverflow.com/a/453001/721644
The compiler is sometimes able to find out which procedure is called by the binding even at compile time. For example, when the actual passed object is non-polymorphic. GCC has two flags -fdevirtualize and -fdevirtualize-speculatively (enabled with -O2, -O3, -Os) which convert virtual calls to direct calls. They are likely applicable to Fortran too.