[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Compilation of methods per class.

To: Gregor Kiczales <Gregor@parc.xerox.com>
cc: commonloops.PARC@Xerox.com
Message-ID: <900925.110735z.10208.lange@lanai.cs.ucla.edu>

>The basic PCL architecture does something very close to what (I believe)
>you are suggesting.  Whether a given port of PCL actually produces code
>of the same quality as your example would compile to depends on a number
>of things.  First among these is whether the fast %FUNCALL and %APPLY
>instructions were properly ported.
>I am not saying that PCL produces exactly the same code, its code looks
>more like:
>(defun foo-runtime12 (self)
>  (let ((*next-methods* '#,(list #'foo-class1-lambda self)))
>    (foo-runtime12-inner self)))
>(defun foo-runtime12-inner (self)
>  (declare (special *next-methods*))
>  (let ((next-method (car *next-methods*)))
>    (foo-class2-body-begin)
>    (%funcall #'next-method self)        ;You should read this as a funcall
>                                         ;that needs no error-checking. The
>                                         ;number of arguments are sure to be
>                                         ;right.
>    (foo-class2-body-end)))
>As compared to your version:   
>   (defun foo-runtime12-lambda (self)
>     (foo-class2-body-begin)
>     (funcall #'foo-class1-lambda self)
>     (foo-class2-body-end))
>PCL does the following extra work:
> % 1 tail-recursive function call (foo-runtime-12 to foo-runtime-12-inner)
> % special variable binding
> % special variable access
> % special variable unbinding
> * unsafe CAR (memory read)

This indeed looks like the kind of code that I was hoping was generated.
However, it doesn't seem to explain the kinds of running time I get on
method calls in generic May Day PCL running in both Lucid and Franz lisp.

Whenever I have the same method defined for several different classes
and call the method at least once for instances of each of those classes,
the time PCL takes to execute the method call goes up, sometimes
dramatically.  Having the same method defined differently on just four
different classes generally almost doubles the amount of time taken when
it is only defined on one class.  The increase in time taken also increases
when auxilary methods are used (even for classes which inherit no auxilaries) or
when classes have primary methods that are overridden.  For one particular
method in my program that has a total of about 20 different primary and 
auxilary definitions on different classes, and which uses those
definitions in various mixin combinations on the runtime classes, the
basic method call takes five times as long as it does when it is
defined one only one class.

The above slowdowns in runtime is what led me to believe that some method
combination or lookup is being done each time a method is called.
This is why I was wondering if anybody (or any of the vendors) had
done method compilation so that "each class would have its own code for
each method."  If that was done, then each method call on a particular
class should take a constant amount of time, regardless of the number of
other places the method was defined, (plus or minus time needed for the
generic function to look up the method's code on the class).

Can you think of any relatively simple modifications to the PCL code
that would do this for people that are willing to accept the increased
code size?  (It would be especially useful if one could declare that
specific time-critical methods should be compiled per class, but that
all other methods use the normal combination method).


- Trent Lange