lisp cond vs. case



Hi John:

Why do you think that eql is slower than string= ?

Have you tested this?

What are you trying to achieve?  I assume that this operation is done a lot, otherwise you wouldn't care about speed.

If it's done a huge number of times, you may want to seriously consider 'uniquizing' your strings using a hash table, and then you can compare using eq.

Or easier & more elegant, create a _symbol_ whose pname is the string, but in a package that you control, and then let the standard 'intern' process do the hashing/uniquizing for you, so that you can now use eq on the interned (& hence uniquized) symbol.

At 06:40 AM 9/13/2013, John Lapeyre wrote:
>Hi,
>
>I wonder when it is appropriate to use use cond vs. case,ecase,...
>
>case compares using eql, which is slower than string=
>
>For example:
>
>(I)
>
>(cond ((string= item "string1") forms1)
>      ((string= item "string2") forms2)
>      ....
>
>(II)
>
>(case item
>      ("string1" forms1)
>      ("string2" forms2)
>     ....
>
>(I) may be faster than (II), but (II) may be
>more clear and less error-prone than (I).
>
>This is a general lisp question, but googling for a bit
>turned up nothing. One could write case-string=.
>My guess is that, in practice, the penalty for
>using eql has not been significant.
>
>In the sbcl source, case, ecase, tyepecase, etc. are
>defined  more-or-less like this:
>
>(defmacro case (keyform &body cases)
>  (case-body 'case keyform cases t 'eql nil nil nil))
>
>The code to generate the bodies is somewhat involved,
>but is mostly error checking.
>
>> (case-body 'mycase 'keyform '((1 1) (2 2)) t '= nil nil nil)
>
> (LET ((#:G1424768 KEYFORM))
>  (DECLARE (IGNORABLE #:G1424768))
>  (COND ((= #:G1424768 '1) NIL 1) ((= #:G1424768 '2) NIL 2)))
>
>--John