[Python-Dev] iterzip()
Tim Peters
tim.one@comcast.net
Mon, 29 Apr 2002 01:05:15 -0400
[Raymond Hettinger]
> ...
> I just timed it and am shocked. iterzip() has exactly the same code
> as zip() except for the final append result to list. So, I expected only
> a microscopic speed-up. I don't see where the huge performance
> improvement came from.
Well, in the zip case you're allocating 4 million bytes worth of integers, 4
bytes at a time, and don't get to reuse any of the space for the duration.
Likewise you're allocating space for a million 3-element tuples, and 4MB
worth of contiguous vector 4 bytes at a time. That's all a real drag.
Cute: I can make the Python genzip run faster than the builtin zip with
"the usual" speed tricks:
from time import clock as now
def run(f, iterables):
start = now()
for tup in f(*iterables):
pass
return now() - start
def genzip(*iterables):
getters = [iter(i).next for i in iterables]
t = tuple
while 1:
yield t([g() for g in getters])
n = 1000000
for f in [zip, genzip]:
print run(f, [xrange(n), xrange(n), xrange(n)]), f.__name__
On my box under current CVS, that yields
C:\Code\python\PCbuild>python -O temp.py
12.3587522419 zip
10.4161551484 genzip
Better, I can get genzip down to 8.34 seconds by skipping the tuple()
call -- in real life, it doesn't really matter whether it returns a tuple or
a list.
One reason zip is faster for me than for you is that pymalloc is enabled by
default in 2.3, and can likely pump out space for a million small tuples
significantly faster than your platform malloc can do it.
> First timing:
> ----------------------
> 19.439999938 zip
> 1.43000006676 iterzip
> 30.1000000238 genzip
If only I had a use for iterzip <wink>.