Как Ada реализует типы 'mod' и 'range'? Каковы последствия производительности?
1 ответ
Непонятно, что вы подразумеваете под "на уровне языка". На уровне Ады они просто есть! и на уровне машины они реализованы так, как вы ожидаете.
Для модульных типов, если вы используете степень 2 для модуля, скомпилированный код использует маски; в противном случае будут тесты.
type Modular is mod 42;
...
procedure T (M : in out Modular) is
begin
M := M + 1;
end T;
переводит (x86_64, -O2) в
_foo__t:
LFB2:
leal 1(%rdi), %eax
cmpb $40, %dil
leal -41(%rdi), %edx
cmovg %edx, %eax
ret
В настоящее время я не пишу на ассемблере, но это выглядит не так уж и плохо (и на языке, который не поддерживает модульные типы, вам придется писать что-то подобное самостоятельно, если этого требует проблема).
Для целочисленных типов реализация снова соответствует ожиданиям, за исключением того, что назначение значения переменной включает проверку ограничения (если только компилятор не докажет, что в этом нет необходимости).
Но на самом деле, для большинства случаев вы не пишете эти операции приращения самостоятельно; если вам нужно перебрать все значения типа, который вы можете сказать
for J in Modular loop
или, если вы объявили Arr : array (Range_Type) of Foo;
,
for J in Arr'Range loop
и нет необходимости проверять действительность J
и, следовательно, нет потери производительности.
Всегда возможно подавить проверки ограничений (в GNAT, -gnatp
подавляет все проверки); но это немного похоже на снятие ремня безопасности, как только вы покинете дорогу!