[comp.lang.scheme] Why are case implementations so slow?

jh@tut.fi (Juha Hein{nen) (12/23/87)

Dispatching of a method is straighforwardly done using a case
expression on the operation symbol.  I have tested the case speed of
three Scheme implementations (CScheme, MacScheme and PC Scheme) and in
all of them cond is faster than case!

Since the case labels have to be symbols, shouldn't the case
expression be faster than the corresponding cond expression?  Is there
some reason why Scheme's case can't be implemted using a computed goto
like in ordinaty programming languages?
-- 
	Juha Heinanen
	Tampere Univ. of Technology
	Finland
	jh@tut.fi (Internet), tut!jh (UUCP)

dyb@IUVAX.CS.INDIANA.EDU (R. Kent Dybvig) (12/25/87)

One reason is that the "natural" expansion of

    (case e0 ((k1 k2 ...) e1 e2 ...) ...)

is

    (let ([tag e0]) (cond ((memv? tag '(k1 k2 ...)) e1 e2 ...) ...))

where "tag" does not occur free in e1 e2 ....

This is surely slower than using the "equivalent" eq? tests when there
is only one key per clause and that key is a symbol.  The Chez Scheme
expander looks for these special cases and expands them "appropriately",
so you should find case as fast as cond.  You could write your own case
macro that does the same thing.

However, it is not practical to turn case into a computed goto unless
there are several keys within a relatively small range of fixnums or
characters.  It could be beneficial, certainly, but Chez Scheme doesn't
bother, and I suspect that most other implementations don't either.

R. Kent Dybvig                 | arpa: dyb@iuvax.cs.indiana.edu
Computer Science Department    | csnet: dyb@indiana
Indiana University             | usenet: ...!ihnp4!iuvax!dyb
Bloomington, IN 47405          | phone: 812/335-6486