reduce()--what is it good for? (was: Re: reduce() anomaly?)

Alex Martelli aleax at aleax.it
Mon Nov 10 10:08:43 EST 2003


Georgy Pruss wrote:

> "Alex Martelli" <aleax at aleax.it> wrote in message
> news:BsJrb.445840$R32.14865362 at news2.tin.it...
> | <...>
> | is way faster than "reduce(operator.add, ..." -- and the advantage in
> | speed *AND* simplicity grows even more when one considers how often
> | that typical reduce is miscoded as "reduce(lambda x, y: x+y, ..." or
> | "reduce(int.__add__, ..." and the like.
> 
> What's the difference between operator.add and int.__add__?

operator.add just adds anything, not caring about the type of what
it's adding.  Internally, it just reaches for the "addition function"
slot and calls that function, period.

> Why is operator.add faster and "better" than int.__add__ if we deal
> with integers?

int.__add__ must also check the type of its argument, and only call
the addition function if the argument is indeed integer, because
otherwise it must raise a TypeError.  The type-checking is normally
needless overhead.

So, we can measure, for example:

alex at lancelot src]$ timeit.py -c -s'import operator' 'map(int.__add__,
xrange(999), xrange(999))'
1000 loops, best of 3: 730 usec per loop

[alex at lancelot src]$ timeit.py -c -s'import operator' 'map(operator.__add__,
xrange(999), xrange(999))'
1000 loops, best of 3: 460 usec per loop

the 999 (useless) type-checks cost 270 microseconds, for a net of
about 270 nanoseconds per check; the 999 additions and the building
of the 999-elements result list cost another 460 microseconds, or
about 460 nanoseconds per operation-and-addition-to-list-of-results.


Alex





More information about the Python-list mailing list