From: Tim Bradshaw
Subject: User-defined method combinations and efficiency
Date: 
Message-ID: <ey3k7t2o71p.fsf@cley.com>
I'm really asking this out of pure laziness - I could do lots of
testing and find out myself but I'm wondering if anyone else has done
the same or more, or if any implementor has comments (this would
obviously be the best answer!).  Also the only
place I do this at present is when I'm about to invoke a shell command
or something else that is going to take seconds so my interest at the
moment is mostly theoretical.

If I define non-trivial method combinations, am I likely to get
serious performance hits for GFs which use those method combinations?
As an example, I have a method combination called `wrapping standard'
which is like standard, but allows an additional kind of `wrapping'
method which happens before and after *everything* and whose methods
are combined in most-specific-innermost order (backwards from
:AROUND).  I wrote this by just looking at the definition of standard
method combination in the hyperspec and extending it in the obvious
way.

I guess what I'm asking is whether implementations do special tricks
to make standard method combination run very fast, which aren't
available (or easily available) to people writing their own.

As I said, my interest at present is mostly theoretical, but I'm
wondering whether user-defined method combinations - which could be a
very powerful tool - is usable in places were performance matters at
all.

Thanks

--tim

From: Marco Antoniotti
Subject: Re: User-defined method combinations and efficiency
Date: 
Message-ID: <y6csn7pa7k6.fsf@octagon.mrl.nyu.edu>
Tim Bradshaw <···@cley.com> writes:

	...

> If I define non-trivial method combinations, am I likely to get
> serious performance hits for GFs which use those method combinations?
> As an example, I have a method combination called `wrapping standard'
> which is like standard, but allows an additional kind of `wrapping'
> method which happens before and after *everything* and whose methods
> are combined in most-specific-innermost order (backwards from
> :AROUND).  I wrote this by just looking at the definition of standard
> method combination in the hyperspec and extending it in the obvious
> way.

Something like the following?

==============================================================================
(in-package "CLAP")

(defvar *standard-extra-method-combination*
  (define-method-combination standard-extra ()
    ((around-first  (:around :first))
     (around-last   (:around :last))
     (around-tagged (:around . *))
     (around-normal (:around))
     (before-first  (:before :first))
     (before-last   (:before :last))
     (before-tagged (:before . *))
     (before-normal (:before))
     (after-first   (:after  :first))
     (after-last    (:after  :last))
     (after-tagged  (:after  . *))
     (after-normal  (:after))
     (primary () :required t)
     )
    (flet ((call-methods (methods)
	     (mapcar #'(lambda (method)
			 `(call-method ,method))
		     methods))
	   (sort-tagged-methods (methods)
	     (stable-sort methods #'subtypep :key #'method-qualifiers))
	   )
      (let* ((before-tagged (sort-tagged-methods before-tagged))
	     (around-tagged (sort-tagged-methods around-tagged))
	     (after-tagged (sort-tagged-methods after-tagged))
	     (around (nconc around-first
			    around-tagged
			    around-normal
			    around-last))
	     (before (nconc before-first
			    before-tagged
			    before-normal
			    before-last))
	     (after (nconc after-last after-normal after-tagged after-first))
	     )
	(let ((form (if (or before after (rest primary))
			`(multiple-value-prog1
			     (progn ,@(call-methods before)
				    (call-method ,(first primary)
						 ,(rest primary)))
			   ,@(call-methods (reverse after)))
			`(call-method ,(first primary)))))
	  (if around
	      `(call-method ,(first around)
			    (,@(rest around) (make-method ,form)))
	      form))))))
==============================================================================


As an aside.  It is kinda annoying that you don't have
FIND-METHOD-COMBINATION in the language.

Cheers


-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Martin Simmons
Subject: Re: User-defined method combinations and efficiency
Date: 
Message-ID: <3c7b716d$0$227$ed9e5944@reading.news.pipex.net>
"Marco Antoniotti" <·······@cs.nyu.edu> wrote in message
····················@octagon.mrl.nyu.edu...
> As an aside.  It is kinda annoying that you don't have
> FIND-METHOD-COMBINATION in the language.

That's because there is no agreement among MOPs about what a method combination
object should be.  Even within a single MOP document, the doesn't seem to be any
way to use the :METHOD-COMBINATION initarg to STANDARD-GENERIC-FUNCTION.

BTW, I've just noticed that ANSI's define-method-combination is supposed to
return the name, not the object (as in CLtL2) so your form won't capture
anything useful.  What would you do with a method combination object anyway?
--
Martin Simmons, Xanalys Software Tools
······@xanalys.com
rot13 to reply
From: Marco Antoniotti
Subject: Re: User-defined method combinations and efficiency
Date: 
Message-ID: <y6cg03o16ms.fsf@octagon.mrl.nyu.edu>
"Martin Simmons" <······@xanalys.com> writes:

> "Marco Antoniotti" <·······@cs.nyu.edu> wrote in message
> ····················@octagon.mrl.nyu.edu...
> > As an aside.  It is kinda annoying that you don't have
> > FIND-METHOD-COMBINATION in the language.
> 
> That's because there is no agreement among MOPs about what a method combination
> object should be.  Even within a single MOP document, the doesn't seem to be any
> way to use the :METHOD-COMBINATION initarg to STANDARD-GENERIC-FUNCTION.
> 
> BTW, I've just noticed that ANSI's define-method-combination is supposed to
> return the name, not the object (as in CLtL2) so your form won't capture
> anything useful.  What would you do with a method combination object anyway?

Use it in the :method-combination initarg? :)

The code is part of a toy implementation of an Aspect Oriented
Programming package.  I needed to define generic functions with the
special method combination.

To tell the truth, I do not remember why I wrote it that way.  It may
have been because of some shortcoming with CMUCL MOP implementation at
that time.

Anyway, it'd be nice to have FIND-METHOD-COMBINATION for symmetry.

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Martin Simmons
Subject: Re: User-defined method combinations and efficiency
Date: 
Message-ID: <3c7b6f87$0$227$ed9e5944@reading.news.pipex.net>
"Tim Bradshaw" <···@cley.com> wrote in message ····················@cley.com...
> I'm really asking this out of pure laziness - I could do lots of
> testing and find out myself but I'm wondering if anyone else has done
> the same or more, or if any implementor has comments (this would
> obviously be the best answer!).  Also the only
> place I do this at present is when I'm about to invoke a shell command
> or something else that is going to take seconds so my interest at the
> moment is mostly theoretical.
>
> If I define non-trivial method combinations, am I likely to get
> serious performance hits for GFs which use those method combinations?
> As an example, I have a method combination called `wrapping standard'
> which is like standard, but allows an additional kind of `wrapping'
> method which happens before and after *everything* and whose methods
> are combined in most-specific-innermost order (backwards from
> :AROUND).  I wrote this by just looking at the definition of standard
> method combination in the hyperspec and extending it in the obvious
> way.
>
> I guess what I'm asking is whether implementations do special tricks
> to make standard method combination run very fast, which aren't
> available (or easily available) to people writing their own.

For a CLOS implementation that compiles method combinations, I wouldn't expect
many (if any) tricks to be done specifically for standard method combinations,
because they expand into simple forms that the compiler should implement
efficiently anyway.  There might be optimizations on the forms themselves and
the method combination is expected to avoid adding unnecessary junk (the ANSI
spec for define-method-combination mentions these cases), but I would expect the
efficiency of a method combination to be directly related to the efficient of
the operators that it uses.
--
Martin Simmons, Xanalys Software Tools
······@xanalys.com
rot13 to reply
From: Tim Bradshaw
Subject: Re: User-defined method combinations and efficiency
Date: 
Message-ID: <ey3g03omq7u.fsf@cley.com>
* Martin Simmons wrote:

> For a CLOS implementation that compiles method combinations, I wouldn't expect
> many (if any) tricks to be done specifically for standard method combinations,
> because they expand into simple forms that the compiler should implement
> efficiently anyway.  There might be optimizations on the forms themselves and
> the method combination is expected to avoid adding unnecessary junk (the ANSI
> spec for define-method-combination mentions these cases), but I would expect the
> efficiency of a method combination to be directly related to the efficient of
> the operators that it uses.

Yes, this is what I hoped.  My thing just expands to a whole load of
CALL-METHOD forms and I assume those get compiled away by magic.
Unfortunately I can't measure it because other stuff like calling the
shell takes hundreds of times as long.

(So why am I worrying?  Do I have to explain? Every C programmer knows
that everything other than actual user performance issues must be
optimized into the ground, and I wouldn't like to think I'm wasting
valuable micronanoseconds).

--tim