[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
union, intersection etc. cons too much with &key arguments
- To: clisp-list@[129.13.115.2]
- Subject: union, intersection etc. cons too much with &key arguments
- From: hoehle@zeus.gmd.de (Jorg-Cyril Hohle)
- Date: Mon, 1 Sep 1997 13:50:43 +0200
Hello,
I just found out that CLISP conses a lot when &REST and &KEY are used
together in a lambda list and APPLY is used on the rest list. This
affects UNION, INTERSECTION, SUBSETP and all other set functions
defined in DEFS1.LSP when one of the :TEST, :TEST-NOT or :KEY
arguments is used and may affect user code as well.
(defun union (list1 list2 &rest rest &key test test-not key)
(declare (ignore test test-not key))
...
(apply #'union (cdr list1) list2 rest))
I verified that CLISP avoids consing when only &REST or &KEY are used
in a lambda list or when the rest argument is empty (nothing to cons).
> (time (intersection '(1 2 3 4 5 6 7 8 9) '(a b c d e f g h i j k l)))
Real time: 0.0 sec.
Run time: 0.0 sec.
Space: 0 Bytes
NIL
> (time (intersection '(1 2 3 4 5 6 7 8 9) '(a b c d e f g h i j k l) :test #'eql :key #'identity))
Real time: 0.0 sec.
Run time: 0.0 sec.
Space: 608 Bytes
NIL
The reason is that EVAL.D:apply_closure():apply_cclosure_key_withlist_:
doesn't treat the case where all &REST arguments are already in the
last argument to APPLY like it does in apply_cclosure_rest_nokey: for
functions with &REST but without &KEY or for functions with &KEY but
without &REST.
Instead of
if (flags & bit(0)) { NEXT(ptr1) = unbound; } # Rest-Parameter
there could be a loop similar to apply_cclosure_rest_nokey: where only
<args_on_stack> values need be pushed onto <args>, constructing the &REST
list in apply_closure() and not in match_cclosure_key().
I don't know how much user code would benefit from such a change but I
know that we're using set functions with :KEY and/or :TEST a lot --
and I thought I'd optimize by using (union x y :test #'eq) instead of
just (union x y) :-(
Regards,
Jo"rg Ho"hle.
Joerg.Hoehle@gmd.de http://zeus.gmd.de/~hoehle/amiga-clisp.html
PS: speed doesn't seem to be affected (except for GC of course).
PPS: I wonder if there's any situation where match_cclosure_key() is
called without rest_arg set to #<unbound>?