Есть ли дополнительные служебные вызовы подпрограмм с полиморфными производными типами, когда тип известен во время компиляции?

У меня есть два производных типа (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), которые преобразуют виртуальные вызовы в прямые вызовы. Они, вероятно, применимы и к Фортрану.

Другие вопросы по тегам