itertools candidate: warehouse()

Peter Otten __peter__ at web.de
Wed Oct 20 02:56:59 EDT 2004


Alex Martelli wrote:

> Raymond Hettinger <vze4rx4y at verizon.net> wrote:
> 
>> [Alex Martelli]
>> > Stylistically, I prefer
>> >     iter(random.random, None)
>> > using the 2-args form of the built-in iter, to
>> >     itertools.starmap(random.random, itertools.repeat(()))
>> 
>> FWIW, I prefer loading the itertools recipes so I can write:
>> 
>>      repeatfunc(random.random)
>> 
>> IMO, that is plainer than both the iter() and starmap() versions.
> 
> I agree, but I cannot distribute Python code containing that, since the
> itertools recipes aren't part of the stdlib.
> 
> 
>> > However, itertools IS a speed demon...:
>> >
>> > kallisti:~/cb alex$ python -m timeit -s 'import random, itertools as
>> > it'
>> > \     > 'list(it.islice(iter(random.random, None), 666))'
>> > 1000 loops, best of 3: 884 usec per loop
>> >
>> > kallisti:~/cb alex$ python -m timeit -s 'import random, itertools as
>> > it'
>> > \     > 'list(it.islice(it.starmap(random.random, it.repeat(())),
>> > 666))' 1000 loops, best of 3: 407 usec per loop
>> 
>> Also time:
>> 
>>     iter(random.random, 1.0)
>> 
>> IIRC, floats compare to each other faster than a float to None.
> 
> Excellent observation!  They do indeed:
> 
> kallisti:~/cb/little_neat_things alex$ python -m timeit -s 'import
> random, itertools as it' 'list(it.islice(iter(random.random, 1.0),
> 666))'
> 1000 loops, best of 3: 564 usec per loop

My first idea was to entirely remove the sentinel, but the benchmarks were a
bit disappointing (not to mention any stylistic damage). So just for the
record:

from random import random
from itertools import *

N = 666

def star():
    return list(islice(starmap(random, repeat(())), N))

class Rand(object):
    next = random
    def __iter__(self): return self

def iter_inf(rand=Rand()):
    return list(islice(iter(rand), N))

def iter_sent(sentinel):
    return list(islice(iter(random, sentinel), N))

$ ./python -m timeit -s"import bench" "bench.star()"
10000 loops, best of 3: 125 usec per loop
$ ./python -m timeit -s"import bench" "bench.iter_sent(None)"
1000 loops, best of 3: 238 usec per loop
$ ./python -m timeit -s"import bench" "bench.iter_sent(1.0)"
10000 loops, best of 3: 175 usec per loop
$ ./python -m timeit -s"import bench" "bench.iter_inf()"
10000 loops, best of 3: 170 usec per loop

Peter




More information about the Python-list mailing list