This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: So far, so good.
- To: Dirk Herrmann <dirk at ida dot ing dot tu-bs dot de>
- Subject: Re: So far, so good.
- From: Miroslav Silovic <silovic at zesoi dot fer dot hr>
- Date: 26 Apr 2000 15:34:47 +0200
- Cc: Telford Tendys <telford at eng dot uts dot edu dot au>, Ken Raeburn <raeburn at raeburn dot org>, Guile Mailing List <guile at sourceware dot cygnus dot com>
- References: <Pine.LNX.4.21.0004260920130.1615-100000@marvin.ida.ing.tu-bs.de>
Dirk Herrmann <dirk@ida.ing.tu-bs.de> writes:
> Can somebody confirm that the compilers are really doing their job
> right, possibly based on assembly code output from the compilers?
> It may well be: If not compiling with strict typing, the
> if-else-if... chain would actually become a sequence of comparisons
> with a constant. If compiling with strict typing, it probably
> wouldn't, but performance with strict typing is expected to be
> horrible anyway.
No, this assumption is completely false. switch and if are meant to be
compiled into different machine-code constructs: if generates a series
of comparisons, while switch generates a jump-table. I haven't heard
of any compiler that is able to transform a bunch of ifs into a
jump-table.
gcc-2.95.2 on SPARC:
int x (int a)
{
switch (a) {
case 0:
return 1;
case 1:
return 2;
case 2:
return 3;
case 3:
return 4;
case 4:
return 5;
case 5:
return 6;
}
}
int y (int a)
{
if (a == 0)
return 1;
if (a == 1)
return 2;
if (a == 2)
return 3;
if (a == 3)
return 4;
if (a == 4)
return 5;
if (a == 5)
return 6;
}
---- this gets compiled into (non-interesting code removed):
:
x:
!#PROLOGUE# 0
!#PROLOGUE# 1
cmp %o0, 5
bgu .LL3
sethi %hi(.LL11), %g2
or %g2, %lo(.LL11), %g2
sll %o0, 2, %g3
ld [%g2+%g3], %o0
jmp %o0
nop
.LL5:
b .LL3
mov 1, %o0
.LL6:
b .LL3
mov 2, %o0
.LL7:
b .LL3
mov 3, %o0
.LL8:
b .LL3
mov 4, %o0
.LL9:
b .LL3
mov 5, %o0
.LL10:
mov 6, %o0
.LL3:
retl
nop
.align 4
.align 4
.LL11:
.word .LL5
.word .LL6
.word .LL7
.word .LL8
.word .LL9
.word .LL10
y:
!#PROLOGUE# 0
!#PROLOGUE# 1
cmp %o0, 0
bne .LL14
cmp %o0, 1
b .LL13
mov 1, %o0
.LL14:
bne .LL15
cmp %o0, 2
b .LL13
mov 2, %o0
.LL15:
bne .LL16
cmp %o0, 3
b .LL13
mov 3, %o0
.LL16:
bne .LL17
cmp %o0, 4
b .LL13
mov 4, %o0
.LL17:
bne .LL18
cmp %o0, 5
b .LL13
mov 5, %o0
.LL18:
be,a .LL13
mov 6, %o0
.LL13:
retl
nop
.LLfe3:
.size y,.LLfe3-y
.ident "GCC: (GNU) 2.95.2 19991024 (release)"
As you can see, the results are based on different principles. Worse,
switch results in the code that performs in a constant time in number
of tests, while ifs perform in linear time.
So, don't remove switches from guile. :)
--
How to eff the ineffable?