Operator overloading is much slower than a method call?

Alex Martelli aleax at aleax.it
Mon Apr 29 13:31:39 EDT 2002


Scott Harris wrote:

> I did some simple timing experiments last night that seem to indicate that
> operator overloading is about 35% slower than a method call on an object.

Yes, in the current implementation, it IS a bit slower

> where the overloaded + operator simply calls the add method.

So you're paying for TWO method calls rather than ONE, that's one factor.
But there's more.  Let's measure.  Script ol.py:

class Overloader:
    def add(self, other):
        return self.__class__()
    def ind(self, other):
        return self.add(other)
    def __add__(self, other):
        return self.add(other)

class NSOverloader(object, Overloader):
    pass

a = b = Overloader()
nsa = nsb = NSOverloader()

import time
r = range(100000)

start=time.clock()
for i in r: pass
stend=time.clock()
over = stend-start

start=time.clock()
for i in r: c = a + b
stend=time.clock()
oper = stend-start

start=time.clock()
for i in r: c = a.add(b)
stend=time.clock()
meth = stend-start

start=time.clock()
for i in r: c = a.ind(b)
stend=time.clock()
indi = stend-start

start=time.clock()
for i in r: c = nsa + b
stend=time.clock()
nsoper = stend-start

start=time.clock()
for i in r: c = nsa.add(b)
stend=time.clock()
nsmeth = stend-start

start=time.clock()
for i in r: c = nsa.ind(b)
stend=time.clock()
nsindi = stend-start


print over, oper, meth, indi, nsoper, nsmeth, nsindi



Results on my box:

[alex at lancelot alex]$ python -O ol.py
0.02 1.05 0.45 0.54 0.81 0.61 0.7
[alex at lancelot alex]$ python -O ol.py
0.03 1.04 0.45 0.54 0.81 0.61 0.7

So: loop overhead negligible for 100,000 operations.

Old-style classes: 4.5 microseconds per operation
for the direct call to .add; 5.4 for the indirect
one; 10.4 for the overloaded-indirection -- a net
cost of 5 microseconds/operation for the overload
itself, plus of course the normal costs of the
indirect-call.

New-style classes: 6.1 for direct call, 7.0 for
indirection, 8.1 for overloaded-indirection -- a
net cost of 1.1 microseconds/operation for the
overload itself, plus etc.

One to five extra microseconds per operation ain't
hay, if you are indeed performing millions of
operations each of which does nothing or very little
(as you talk about vector operations in your program,
though, I wonder if each operation couldn't perform
enough work to make this overhead negligible).


Alex




More information about the Python-list mailing list