Static typing [was Re: Python and the need for speed]

Chris Angelico rosuav at gmail.com
Sun Apr 16 15:00:34 EDT 2017


On Mon, Apr 17, 2017 at 4:43 AM, bartc <bc at freeuk.com> wrote:
>>
>> For what it's worth, on my machine (2GB RAM and 1.2GHz CPU) I can add up
>> 100
>> million ints in 14 seconds:
>>
>> py> with Stopwatch():
>> ...     sum(range(100000000))
>> ...
>> 4999999950000000
>> time taken: 14.032116 seconds
>
>
> I'm surprised it took that long. If a 'range' is no longer expanded to a
> list, and 'sum' is built-in, isn't there a formula that can be used to sum a
> sequence? At least when the step is +1.

Sure! If all you care about is winning benchmarks, you could easily
create a sum() that recognizes when it's given a range object. Let's
start with a baseline. I took the code from the link Steven posted
(and renamed Timer to Stopwatch), and:

4999999950000000
time taken: 1.143872 seconds

Ehh, too fast. I'll add another zero onto it.

499999999500000000
time taken: 11.413530 seconds

Better. Now then.

_orig_sum = sum
def sum(iterable, start=0):
    if isinstance(iterable, range) and iterable.step == 1:
        # I don't feel like dealing with non-unity steps
        n = iterable.stop * (iterable.stop - 1) // 2
        if iterable.start:
            n -= iterable.start * (iterable.start + 1) // 2
        return start + n
    return _orig_sum(iterable, start)

499999999500000000
time taken: 0.000016 seconds

Hey look! We win at benchmarks. Of course, to do this, I had to make
every other sum() call slightly slower (maybe not a lot, but slower by
the price of one instance check at best), but what a benefit!

ChrisA



More information about the Python-list mailing list