Method much slower than function?

Peter Otten __peter__ at web.de
Thu Jun 14 12:43:44 EDT 2007


Peter Otten wrote:

> Leo Kislov wrote:
> 
>> On Jun 13, 5:40 pm, ido... at gmail.com wrote:
>>> Hi all,
>>>
>>> I am running Python 2.5 on Feisty Ubuntu. I came across some code that
>>> is substantially slower when in a method than in a function.
>>>
>>> >>> cProfile.run("bar.readgenome(open('cb_foo'))")
>>>
>>>          20004 function calls in 10.214 CPU seconds
>> 
>>> >>> cProfile.run("z=r.readgenome(open('cb_foo'))")
>>>
>>>          20004 function calls in 0.041 CPU seconds
>>>
>> 
>> I suspect open files are cached so the second reader
>> picks up where the first one left: at the of the file.
>> The second call doesn't do any text processing at all.
>> 
>>   -- Leo
> 
> Indeed, the effect of attribute access is much smaller than what the OP is
> seeing:

I have to take that back
 
> $ cat iadd.py
> class A(object):
>     def add_attr(self):
>         self.x = 0
>         for i in xrange(100000):
>             self.x += 1
>     def add_local(self):
>         x = 0
>         for i in xrange(100000):
>             x += 1
> 
> add_local = A().add_local
> add_attr = A().add_attr
> $ python2.5 -m timeit -s 'from iadd import add_local' 'add_local()'
> 10 loops, best of 3: 21.6 msec per loop
> $ python2.5 -m timeit -s 'from iadd import add_attr' 'add_attr()'
> 10 loops, best of 3: 52.2 msec per loop

Iddo, adding integers is not a good model for the effect you are seeing.
Caching, while happening on the OS-level isn't, either.

As already mentioned in this thread there is a special optimization for

some_string += another_string

in the Python C-source. This optimization works by mutating on the C-level
the string that is immutable on the Python-level, and is limited to cases
where there are no other names referencing some_string. The statement

self.s += t

is executed internally as

tmp = self.s [1]
tmp += t     [2]
self.s = tmp [3]

where tmp is not visible from the Python level. Unfortunately after [1]
there are two references to the string in question (tmp and self.s) so the
optimization cannot kick in.

Peter




More information about the Python-list mailing list