[Python-Dev] Re: opcode performance measurements

Neal Norwitz neal@metaslash.com
Sat, 02 Feb 2002 09:38:33 -0500

Samuele Pedroni wrote:
> From: Jeremy Hylton <jeremy@zope.com>
> > >>>>> "SP" == Samuele Pedroni <pedronis@bluewin.ch> writes:
> ...
> >   SP> one can try to guess the slots of a class looking for the
> >   SP> "self.attr" pattern at compile time in a more or less clever
> >   SP> way.  The set of compile-time guessed attrs will be passed to
> >   SP> MAKE_CLASS which will construct the runtime guess using the
> >   SP> union of the super-classes guesses and the compile time guess
> >   SP> for the class.  This information can be used to layout a dlict.
> >
> > Right!  There's another step necessary to take advantage though.  When
> > you execute a method you don't know the receiver type
> > (self.__class__).  So you need to specialize the bytecode to a
> > particular receiver the first time the method is called.  Since this
> > could be relatively expensive and you don't know how often the method
> > will be executed, you need to decide dynamically when to do it.  Just
> > like HotSpot.

Why not assume the general case is the most common, ie, that the
object is an instance of this class or one of its subclasses?
That way you could do the specialization at compile time.  And
for the (presumably) few times that this isn't true fallback to another
technique, perhaps like HotSpot.

Also, doesn't calling a base class method as:
	Base.method(self)	# in particular __init__()

create problems if you specialize for a specific class?  Or does
specialization necessarily mean for a subclass and all its base clases?

> Right, because with multiple inheritance you cannot make the layout
> of a subclass compatible with that of *all* superclasses, so simple
> monomorphic inline caches will not work :(.

ISTM that it would be best to handle single inheritance first.
Multiple inheritance could perhaps be handled for the class with
the most commonly referenced attribute (assuming 2+ classes don't
define the same attr.  And use a fallback technique for all other cases.

> > We probably have to worry about a class or instance being modified in
> > a way that invalidates the dlict offsets computed.  (Not sure here,
> > but I think that's the case.)  If so, we probably need a different

Right, if an attr is deleted, methods added/removed dynamically, etc.

> > object -- call it a template -- that represents the concrete layout
> > and is tied to unmodified concrete class.  When objects or classes are
> > modified in dangerous ways, we'd need to invalidate the template
> > pointer for the affected instances.

By using a template, doesn't that become a dict lookup again?

> These are all interesting topics, although from these
> more or less informal discussions to results there is
> a lot of details and code :(.

I agree.  Since we can't know what will be optimal, it seems safer
to keep the existing functionality as a fallback case and try 
to improve things with small steps (eg, single inheritance, first).

> But already improving the global lookup thing
> would be a good step.