Do deep inheritance trees degrade efficiency?

Anthra Norell anthra.norell at bluewin.ch
Thu Mar 19 09:24:21 EDT 2009


Bruno Desthuilliers wrote:
> Chris Rebert a écrit :
>> On Wed, Mar 18, 2009 at 6:09 AM, Anthra Norell 
>> <anthra.norell at bluewin.ch> wrote:
>>> Would anyone who knows the inner workings volunteer to clarify 
>>> whether or
>>> not every additional derivation of a class hierarchy adds an 
>>> indirection to
>>> the base class's method calls and attribute read-writes. In C++, I 
>>> suppose,
>>> a three-level inheritance would resolve into something like
>>> *(*(*(*(base_class_method ())))).
>>
>> There's no effect on attribute read-writes as they all take place
>> within the single __dict__ of the instance.
>
> Except when:
> - the attribute is a computed one (property or other descriptor)
> - (for read access) the attribute is not set in the instance's dict.
>
>> As for method lookup, it
>> doesn't 
>
> make much difference - the very same lookup rules apply, and it's the 
> descriptor protocol (as implemented by the 'function' type) that takes 
> care of returning a method object (mostly a partial application of the 
> function to the instance or class) when appropriate.
>
> (snip)
>
>> However, you shouldn't really worry about the inefficiency of a deep
>> inheritance tree as Python
>
> is probably not the right tool for the job if one have such efficiency 
> concerns.
>
> (snip)
>
>> [Note: I'm purposefully ignoring the fact that methods and attributes
>> are in reality looked up in the exact same way for
>> simplicity/clarity.]
>
> Ah, ok - then please don't take the above remarks as a personal 
> offense !-)
>
> (still posting this since it might be of interest to the OP or someone 
> else).
> -- 
> http://mail.python.org/mailman/listinfo/python-list
The OP (that's me) thankfully acknowledges all contributions. The upshot 
of it all seems to be that there are countless ways for a compiler or 
interpreter to handle access through class hierarchies. I did a very 
crude test myself, like this:

 >>> class A:
         def do (self): pass
 >>> class B (A): pass
 >>> class C (B): pass
 >>> class D (C): pass
 >>> class E (D): pass   # Got to stop somewhere

 >>> a = A ()
 >>> for i in xrange (1000000):
            a.do ()
11 seconds

 >>> e = E ()
 >>> for i in xrange (1000000):
             e.do ()
14 seconds

No significant difference indeed !

Frederic





More information about the Python-list mailing list