[Bug-openmcl] ccl::%car vs ccl::car
gb at clozure.com
Wed Jan 7 03:02:30 MST 2004
On Wed, 7 Jan 2004, bryan o'connor wrote:
> #'memeql dies horribly if the list is improper and there
> is no match. for example: (memeql 1 '(3 4 . 5))
> the problem seems to be the call to ccl::%car. since
> there is also a ccl::car, i wonder if %car assumes a
> list in order to shave some instructions.
> if so, the fix is probably to #'memeql to insure a proper
> list. or moving higher up the call chain, to fix the
> callers like #'set-difference.
> a reduced test case is below.
CCL::MEMEQL is used to implement MEMBER in the case where the :KEY and
:TEST default to #'IDENTITY and #'EQL.
The problem isn't that unsafe operations are used in the two loops
in MEMEQL, it's that they're used incorrectly. (Both loops are
functionally identical except for whether EQ or EQL is used.)
Both loops can be made faster (and safer) by:
a) eliminating the explicit LISTP test on entry.
b) using ENDP instead of NULL as the terminating clause in the DO*.
c) using non-type-checking versions of CAR and CDR, since the only
cases where either of these operations can be performed are
those where ENDP has already typechecked their arguments.
This was probably written in about 1986 (and probably rewritten
at least once since then, so that a previously "safe" unsafe operation
became unsafe), and the performance hit associated with the extra
typechecking was probably much greater than it is today. Saving
a cycle here and there doesn't buy you that much, unless there's
a loop and/or a frequently-called primitive function involved,
and both of those things are involved here.
On the other hand, CCL::ASSEQL also uses unsafe operations, and there's
no excuse in that case.
BTW, are you running a test suite or are you just finding this stuff ?
More information about the Bug-openmcl