map del efficiency python2.2 and 2.1

Alex Martelli aleax at aleax.it
Wed Jul 17 03:32:16 EDT 2002


Bengt Richter wrote:

> On Tue, 16 Jul 2002 15:53:43 GMT, Alex Martelli <aleax at aleax.it> wrote:
> 
>>John Hunter wrote:
>>        ...
>>> def pairs(l):
>>>     return [(l[i], l[i+1]) for i in range(0, len(l), 2)]
>                                        ^^^^^
        ...
>>def pairs(L):
>>    for i in xrange(0, len(L), 2):
>               ^^^^^^
>               ^
>>        yield L[i], L[i+1]
>>
>>but that's a minor issue, I guess.
>>
>>Another likely performance boost in 2.2 would be:
>>
>>m = dict(pairs(seq))
>>
>>with pairs coded as here shown.
> 
> In case John didn't notice, that little 'x' your finger likely
> typed automatically probably made some difference too ;-)

Yep, but John had used xrange in other spots of his code,
so I didn't think I needed to explain better.  Still, that
may have been an error on my part.  So, the better explanation:
range and list comprehensions build lists and thus may have
to allocate lots of memory.  xrange and generators don't build
any list but rather return one item at a time as needed.

But the importance of using xrange vs range is minor -- yes
it does make SOME difference, but it's small.  See:

from __future__ import generators
import time, gc

L = range(300 * 1000)

def timit(f):
    start = time.clock()
    m = dict(f(L))
    stend = time.clock()
    print f.__name__, stend-start

def pairs_lc_ra(L):
    return [ (L[i],L[i+1]) for i in range(0, len(L), 2) ]

def pairs_lc_xr(L):
    return [ (L[i],L[i+1]) for i in xrange(0, len(L), 2) ]

def pairs_ge_ra(L):
    for i in range(0, len(L), 2):
        yield L[i], L[i+1]

def pairs_ge_xr(L):
    for i in range(0, len(L), 2):
        yield L[i], L[i+1]

gc.disable()

for i in range(3):
    for f in pairs_lc_ra, pairs_lc_xr, pairs_ge_ra, pairs_ge_xr:
        timit(f)


[alex at lancelot MyDocuments]$ python pa.py
pairs_lc_ra 0.53
pairs_lc_xr 0.52
pairs_ge_ra 0.29
pairs_ge_xr 0.28
pairs_lc_ra 0.52
pairs_lc_xr 0.52
pairs_ge_ra 0.28
pairs_ge_xr 0.28
pairs_lc_ra 0.52
pairs_lc_xr 0.52
pairs_ge_ra 0.28
pairs_ge_xr 0.28

This is with 2.2.1.  2.3 built from CVS lowers generator's advantage:

[alex at lancelot src]$ ./python pa.py
pairs_lc_ra 0.44
pairs_lc_xr 0.4
pairs_ge_ra 0.29
pairs_ge_xr 0.28
pairs_lc_ra 0.43
pairs_lc_xr 0.4
pairs_ge_ra 0.29
pairs_ge_xr 0.29
pairs_lc_ra 0.43
pairs_lc_xr 0.39
pairs_ge_ra 0.29
pairs_ge_xr 0.29

but even here, using generators rather than list comprehensions
seems still much more important than using xrange rather than range.


Alex





More information about the Python-list mailing list