Hacker News new | ask | show | jobs
by moreati 4860 days ago
Great presentation, thank you for making me aware of an aspect of Python performance. One slide struck me as odd - the "basically pythonic" squares() function. I understand it's a chosen example to illustrate a point, I just hope people aren't writing loops like that. You inspired me to measure it

    $ cat squares.py
    def squares_append(n):
        sq = []
        for i in xrange(n):
            sq.append(i*i)
        return sq

    def squares_comprehension(n):
        return [i*i for i in xrange(n)]
    $ PYTHONPATH=. python -m timeit -s "from squares import squares_append" "squares_append(1000)"
    10000 loops, best of 3: 148 usec per loop
    $ PYTHONPATH=. python -m timeit -s "from squares import squares_comprehension" "squares_comprehension(1000)"
    10000 loops, best of 3: 74.1 usec per loop
    $ PYTHONPATH=. pypy -m timeit -s "from squares import squares_append" "squares_append(1000)"
    10000 loops, best of 3: 46.9 usec per loop
    $ PYTHONPATH=. pypy -m timeit -s "from squares import squares_comprehension" "squares_comprehension(1000)"
    100000 loops, best of 3: 8.67 usec per loop
I'm curious to know how many allocations/copies a list comprehension saves in CPython/PyPy. However I wouldn't begin to know how to measure it.
1 comments

If you really want power, use NumPy:

    from numpy import arange

    def squares_numpy(n):
        a = arange(n)
        return a * a

    $ python -m timeit -s "from squares import squares_append" "squares_append(1000)"
    10000 loops, best of 3: 130 usec per loop
    $ python -m timeit -s "from squares import squares_comprehension" "squares_comprehension(1000)"
    10000 loops, best of 3: 95.4 usec per loop
    $ python -m timeit -s "from squares import squares_numpy" "squares_numpy(1000)"
    100000 loops, best of 3: 5.31 usec per loop