Основным фактором является то, что нестабильность типов вызывает динамическую диспетчеризацию, когда языку необходимо определить, какой метод (для некоторой функции, принимающей нестабильную переменную типа) необходимо вызывать во время выполнения.В статическом случае это компилируется в прямой вызов функции (в основном оператор goto в машинном коде).Однако с нестабильным кодом он должен иметь код, который читает список всех методов для этой функции и находит тот, который соответствует.Динамическая диспетчеризация также означает, что она не может быть встроенной, что существенно ограничивает возможности оптимизатора.
Особая проблема заключается в том, что нестабильность типа является ядовитой, например, не ограничивается местом ее возникновения.Таким образом, вы можете превратить узкий цикл в цикл, который выполняет динамическую диспетчеризацию при каждой операции.
Однако в Julia 1.x компилятор может выполнить «оптимизацию небольшого объединения», что означает, что если компилятор определяет, чтозначение должно быть одним небольшим числом конкретных типов (в настоящее время ≤ 4), тогда вместо динамической отправки он может проверить, является ли фактический тип какой-либо из этих четырех возможностей, и сгенерировать ветку, в которой конкретный тип значения равенизвестной и динамичной отправки можно полностью избежать.Например, если значение может быть Int
или nothing
, то компилятор может проверить, является ли оно nothing
, и обработать этот случай, в противном случае он знает, что значение должно быть Int
, и он может сгенерировать эффективный код для этого.кейс тоже.