Probiers doch einfach mal aus:
https://godbolt.org/z/rKE6nnaW8
Code: Alles auswählen
procedure test(i: Integer);
begin
case i of
0..9: Foo;
10..99: Bar;
100..999: Baz;
end;//case
end;
-O1:
Code: Alles auswählen
test(longint):
pushq %rbp
movq %rsp,%rbp
leaq -16(%rsp),%rsp
movl %edi,-8(%rbp)
movl %edi,%eax
testl %edi,%edi
jl .Lj12
subl $9,%eax
jle .Lj13
subl $90,%eax
jle .Lj14
subl $900,%eax
jle .Lj15
jmp .Lj12
.Lj13:
call foo()
jmp .Lj11
.Lj14:
call bar()
jmp .Lj11
.Lj15:
call baz()
.Lj12:
.Lj11:
movq %rbp,%rsp
popq %rbp
ret
Subl ist Subtraktion und jle ist jump lesser equal. Das ist im grunde also:
Code: Alles auswählen
if i < 0 then
Exit;
i -= 9;
if i <= 0 then
begin
Foo;
Exit;
end;
i -= 90;
if i <= 0 then
Bar;
Exit;
end;
i -= 900;
if i <= 0 then
Baz;
Exit;
end;
Exit;
Mit -O3 ist das das ein bisschen "aufgeräumter" aber im grunde das selbe:
Code: Alles auswählen
test(longint):
leaq -8(%rsp),%rsp
movl %edi,%eax
testl %edi,%edi
jl .Lj12
subl $9,%eax
jle .Lj13
subl $90,%eax
jle .Lj14
subl $900,%eax
jle .Lj15
jmp .Lj12
.Lj13:
call foo()
jmp .Lj11
.Lj14:
call bar()
jmp .Lj11
.Lj15:
call baz()
.Lj12:
.Lj11:
leaq 8(%rsp),%rsp
ret
Tatsächlich ist einer der Gründe warum man Case...of vor If-then-else bevorzugen sollte, das es dem compiler die Freiheit lässt code genau so zu übersetzen und zu optimieren. Deshalb sorgt Case..Of meist für effizienteren code als if-then-else