Feature suggestion: sum() ought to use a compensated summation algorithm

George Sakkis george.sakkis at gmail.com
Sat May 3 20:43:57 EDT 2008


On May 3, 7:12 pm, Ivan Illarionov <ivan.illario... at gmail.com> wrote:
> On Sun, 04 May 2008 00:31:01 +0200, Thomas Dybdahl Ahle wrote:
> > On Sat, 2008-05-03 at 21:37 +0000, Ivan Illarionov wrote:
> >> On Sat, 03 May 2008 20:44:19 +0200, Szabolcs Horvát wrote:
>
> >> > Arnaud Delobelle wrote:
>
> >> >> sum() works for any sequence of objects with an __add__ method, not
> >> >> just floats!  Your algorithm is specific to floats.
>
> >> > This occurred to me also, but then I tried
>
> >> > sum(['abc', 'efg'], '')
>
> >> Interesting, I always thought that sum is like shortcut of
> >> reduce(operator.add, ...), but I was mistaken.
>
> >> reduce() is more forgiving:
> >> reduce(operator.add, ['abc', 'efg'], '' ) # it works 'abcefg'
> > Hm, it works for lists:
> > sum(([1], [2]), [])
> > [1, 2]

So it's not reduce() that is more forgiving, it's sum() that makes an
exception for strings only.


> > However I find the seccond argument hack ugly. Does the sum way have any
> > performance advantages over the reduce way?
>
> Yes, sum() is faster:
>
> $ python -m timeit "" "sum([[1], [2], [3, 4]], [])"
> 100000 loops, best of 3: 6.16 usec per loop
>
> $ python -m timeit "import operator" \
> "reduce(operator.add, [[1], [2], [3, 4]])"
> 100000 loops, best of 3: 11.9 usec per loop

Not really; you measure the import and the attribute access time in
the second case. sum() is 2x faster for adding numbers only:

# Adding integers
python -mtimeit --setup="x=[1]*100" "sum(x)"
100000 loops, best of 3: 4.87 usec per loop
python -mtimeit --setup="from operator import add; x=[1]*100"
"reduce(add,x)"
100000 loops, best of 3: 10.1 usec per loop

# Adding floats
python -mtimeit --setup="x=[1.0]*100" "sum(x)"
100000 loops, best of 3: 5.14 usec per loop
python -mtimeit --setup="from operator import add; x=[1.0]*100"
"reduce(add,x)"
100000 loops, best of 3: 10.1 usec per loop

# Adding tuples
python -mtimeit --setup="x=[(1,)]*100" "sum(x,())"
10000 loops, best of 3: 61.6 usec per loop
python -mtimeit --setup="from operator import add; x=[(1,)]*100"
"reduce(add,x,())"
10000 loops, best of 3: 66.3 usec per loop

# Adding lists
python -mtimeit --setup="x=[[1]]*100" "sum(x,[])"
10000 loops, best of 3: 79.9 usec per loop
python -mtimeit --setup="from operator import add; x=[[1]]*100"
"reduce(add,x,[])"
10000 loops, best of 3: 84.3 usec per loop

George



More information about the Python-list mailing list