Я пишу код моделирования (почти) с нуля и хочу использовать функции ООП из фортрана, чтобы упростить его обслуживание. На семинаре по Фортрану я узнал, что нужно быть осторожным при использовании функций ООП в критически важных для производительности частях кода.
Моим наивным первым подходом (игнорируя предупреждение) был бы следующий фрагмент. Фоном является расчет энергии системы, для которой нужен потенциал взаимодействия. Для этого потенциала я использую абстрактный тип (потенциал). Затем все пользователи могут добавлять свои собственные потенциалы в качестве расширений и определять ключевое слово, которое используется для выделения их потенциала. Расчет энергии в основной программе не меняется.
module system_mod
implicit none
type, abstract :: potential
contains
procedure(init), deferred :: init
procedure(eval), deferred :: eval
end type
type, extends(potential) :: my_potential
! some parameters
contains
procedure :: init => init_my_potential
procedure :: eval => eval_my_potential
end type
! omitted: other extensions of 'potential'
! and abstract interface of potential
type :: system
! some components
class(potential), allocatable :: pair_potential
contains
procedure :: init ! subroutine, which is used to allocate pair_potential depending on a passed keyword
end type
contains
! implementation of all routines
end module system_mod
program main
use system_mod, only: potential, my_potential, system
implicit none
character(len=3) :: keyword !
integer :: i
real :: coordinates(n,3) ! n is a huge number
real :: energy, system_energy
type(system) :: test_system
call test_system%init ( keyword )
! keyword tells which of the extensions of 'potential' is allocated
do i = 1, n
energy = test_system%pair_potential%eval ( ... )
system_energy = system_energy + energy
end do
end program
Я думаю, что моя главная проблема, связанная с производительностью, заключается в том, что я не понимаю, что на самом деле делает компилятор во время компиляции и какие вещи выполняются во время выполнения.
Итак, мои вопросы:
- Как и когда компилятор проверяет, какой экземпляр eval использовать?
- Когда ключевое слово известно во время компиляции, выполняется ли проверка типа на каждой итерации цикла?
- Было бы лучше, например, использовать указатель процедуры в основной программе и связать его в начале с соответствующей процедурой 'eval'?
Заранее большое спасибо!