Fredrik Lundh said:
Alex said:
But of course that only does it once, and I don't want to have to copy
and paste the append line. Perhaps there's a better way than this.
def makeseries(N):
series = [N]
append = series.append
for tailer in xrange(N-1, -1, -1):
append(tailer)
append(tailer)
But Now You've Violated The DRY Principle!!!
Just as with any other unrolled loop, yes -- loop unrolling is an
optimization which is based exactly on exchanging some textual
repetition for a tiny bit more speed.
Of course, optimizations can easily be premature, and in any case need
to be checked by measurement. E.g., here are a few variations:
def makeseries_a(N):
series = [N]
append = series.append
for tailer in xrange(N-1, -1, -1):
append(tailer)
append(tailer)
return series
def makeseries_b(N):
series = [N]
append = series.append
for tailer in xrange(N-1, -1, -1):
for x in (1,2):
append(tailer)
return series
def makeseries_c(N):
series = [N]
extend = series.extend
for tailer in xrange(N-1, -1, -1):
extend((tailer,tailer))
return series
def makeseries_d(N):
series = [N]
extend = series.extend
for tailer in xrange(N-1, -1, -1):
extend((tailer,)*2)
return series
And:
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_a(100)'
10000 loops, best of 3: 31.7 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_b(100)'
10000 loops, best of 3: 57.4 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_c(100)'
10000 loops, best of 3: 36.2 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_d(100)'
10000 loops, best of 3: 54.4 usec per loop
So, it would seem that (at least among these few variations) I had
guessed right, this time -- the loop-unrolling is beneficial and append
is minutely better than extend. Of course, the yanking from the loopbody
of the boundmethod is also a key optimization here -- with unyanked
(more natural) versions [[i.e., calling series.append or series.extend
right in the loop body]] I measure:
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_a(100)'
10000 loops, best of 3: 57.3 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_b(100)'
10000 loops, best of 3: 83.5 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_c(100)'
10000 loops, best of 3: 48 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_d(100)'
10000 loops, best of 3: 68.4 usec per loop
Alex