Есть ли дополнительные служебные вызовы подпрограмм с полиморфными производными типами, когда тип известен во время компиляции?
У меня есть два производных типа (child1 и child2), которые оба выходят из одного абстрактного типа (type, abstract :: parent
). Абстрактный тип имеет отложенную связанную процедуру.
Я хочу вызвать подпрограмму, которая выполняет некоторые вещи (критичные к производительности) в зависимости от типа ребенка, передаваемого в качестве входных данных. Я могу придумать два варианта:
- Подпрограмма принимает
class(parent), intent(inout) :: type_in
в качестве ввода. Реализации для детей затем делаются в рамкахselect type (type_in)
построить. - Я пишу две подпрограммы, одна с
type(child1), intent(inout) :: type_in
и один сtype(child2), intent(inout) :: type_in
и предоставить явный интерфейс для перегрузки имени подпрограммы.
Первый вариант учитывает реализации, в которых расширение родителя неизвестно во время компиляции, но в моем случае это не обязательно. Это также сохраняет некоторые строки кода, потому что только часть его отличается для детей.
Мой вопрос: есть ли дополнительные издержки в первом варианте, потому что я реализовал ввод как полиморфные данные, когда тип известен во время компиляции?
1 ответ
Да, существует дополнительная стоимость виртуального звонка. Таблица виртуальных методов (как ее называют на других языках) используется и ищется правильная процедура для вызова. Стоимость, вероятно, будет аналогична стоимости вызова виртуальной функции в C++, см. /questions/43425142/virtualnyie-funktsii-i-proizvoditelnost-c/43425152#43425152
Компилятор иногда может выяснить, какая процедура вызывается связыванием даже во время компиляции. Например, когда фактический переданный объект является неполиморфным. GCC имеет два флага -fdevirtualize
а также -fdevirtualize-speculatively
(включается с -O2, -O3, -Os), которые преобразуют виртуальные вызовы в прямые вызовы. Они, вероятно, применимы и к Фортрану.