Рантайм-проверка на диапазон отнимает примерно 10% быстродейсвия молотильных операций. Но обычных операциях все не так страшно. INT32+INT32 на 2..3% быстрее чем INT32+INT8
из-за более "movl %ebx,%eax" чем "movzbl %bl,%eax".
Код: Выделить всё
program addspeed;
{$mode objfpc}
uses
sysutils,dateutils;
var
i2: longint;
i3: longint;
i1: byte;
i: longint;
dt: tdatetime;
begin
i1:= 1;
i2:= 0;
dt:= now;
for i:=0 to 100000000 do i2:= i2 + i1;
writeln('longint + byte: ',millisecondof(now - dt),' ms');
i3:= 1;
i2:= 0;
dt:= now;
for i:=0 to 100000000 do i2:= i2 + i3;
writeln('longint + longint: ',millisecondof(now - dt),' ms');
end.
fpc -O3 -a <file>
Код: Выделить всё
int32 + int8
incl %edx
movzbl %bl,%eax
addl %esi,%eax
movl %eax,%esi
cmpl $100000000,%edx
jl .Lj11
int32 + int32
incl %edx
movl %ebx,%eax
addl %esi,%eax
movl %eax,%esi
cmpl $100000000,%edx
jl .Lj46
fpc -O3 -a -Cr - Co <file> // range & overflow checks
Код: Выделить всё
int32 + int8
.Lj11:
addl $1,%edx
movzbl %bl,%eax
addl %esi,%eax
jno .Lj14
call FPC_OVERFLOW
.Lj14:
movl %eax,%esi
cmpl $100000000,%edx
jl .Lj11
int32 + int32
.Lj47:
addl $1,%edx
movl %ebx,%eax
addl %esi,%eax
jno .Lj50
call FPC_OVERFLOW
.Lj50:
movl %eax,%esi
cmpl $100000000,%edx
jl .Lj47
Добавлено спустя 14 минут 3 секунды:Самопальная проверка на диапазон
Код: Выделить всё
for i:=0 to 100000000 do begin
if i2 > -1 then i2:= i2 + i1;
end;
Приводит к 20..25% замедлению на молотильных операциях :
Код: Выделить всё
.Lj11:
incl %edx
cmpl $-1,%esi
jng .Lj13
movzbl %bl,%eax
addl %esi,%eax
movl %eax,%esi
.Lj13:
cmpl $100000000,%edx
jl .Lj11
Код: Выделить всё
.Lj48:
incl %edx
cmpl $-1,%esi
jng .Lj50
movl %ebx,%eax
addl %esi,%eax
movl %eax,%esi
.Lj50:
cmpl $100000000,%edx
jl .Lj48
хотя занимает совсем мало инструкций. Но на молочении даже это "совсем мало" заметно.
Добавлено спустя 4 минуты 24 секунды:При дефолтной оптимизации самопальная проверка диапазона снижает скорость молочения на 5..6%.