Skip to content

Instantly share code, notes, and snippets.

@RonnyPfannschmidt
Last active December 26, 2015 20:39
Show Gist options
  • Save RonnyPfannschmidt/7209843 to your computer and use it in GitHub Desktop.
Save RonnyPfannschmidt/7209843 to your computer and use it in GitHub Desktop.
experiment i'd like to understand why the new one is only barely as fast as the old one
roundrobin 0.148742198944
roundrobin_stable 0.169327974319
roundrobin_rotate 0.246076822281
roundrobin
204064 function calls in 1.340 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
2000 0.000 0.000 0.000 0.000 :0(iter)
20 0.000 0.000 0.000 0.000 :0(len)
101000 0.320 0.000 0.320 0.000 :0(next)
1 0.000 0.000 0.000 0.000 :0(range)
1 0.008 0.008 0.008 0.008 :0(setprofile)
2020 0.008 0.000 0.008 0.000 itertool_example.py:10(<genexpr>)
99020 0.664 0.000 0.992 0.000 itertool_example.py:6(roundrobin)
1 0.340 0.340 1.332 1.332 itertool_example.py:70(loop)
1 0.000 0.000 1.340 1.340 profile:0(<function loop at 0x2776488>)
0 0.000 0.000 profile:0(profiler)
roundrobin_stable
404044 function calls in 2.532 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
99000 0.312 0.000 0.312 0.000 :0(append)
2000 0.012 0.000 0.012 0.000 :0(iter)
101000 0.300 0.000 0.300 0.000 :0(next)
101000 0.340 0.000 0.340 0.000 :0(popleft)
1 0.000 0.000 0.000 0.000 :0(range)
1 0.000 0.000 0.000 0.000 :0(setprofile)
99020 1.272 0.000 2.244 0.000 itertool_example.py:21(roundrobin_stable)
2020 0.008 0.000 0.020 0.000 itertool_example.py:23(<genexpr>)
1 0.288 0.288 2.532 2.532 itertool_example.py:70(loop)
1 0.000 0.000 2.532 2.532 profile:0(<function loop at 0x2776488>)
0 0.000 0.000 profile:0(profiler)
roundrobin_rotate
305044 function calls in 1.840 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
2000 0.004 0.000 0.004 0.000 :0(iter)
101000 0.292 0.000 0.292 0.000 :0(next)
2000 0.008 0.000 0.008 0.000 :0(popleft)
1 0.000 0.000 0.000 0.000 :0(range)
99000 0.304 0.000 0.304 0.000 :0(rotate)
1 0.000 0.000 0.000 0.000 :0(setprofile)
99020 0.936 0.000 1.560 0.000 itertool_example.py:36(roundrobin_rotate)
2020 0.016 0.000 0.020 0.000 itertool_example.py:38(<genexpr>)
1 0.280 0.280 1.840 1.840 itertool_example.py:70(loop)
1 0.000 0.000 1.840 1.840 profile:0(<function loop at 0x2776488>)
0 0.000 0.000 profile:0(profiler)
from __future__ import print_function
from collections import deque
from itertools import cycle, islice
import pytest
def roundrobin(*iterables):
" >> roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
iters = cycle(iter(it) for it in iterables)
while pending:
try:
for item in iters:
yield next(item)
except StopIteration:
pending -= 1
iters = cycle(islice(iters, pending))
def roundrobin_stable(*iterables):
" >> roundrobin('ABC', 'D', 'EF') --> A D E B F C"
items = deque(iter(x) for x in iterables)
pop = items.popleft
push = items.append
while items:
item = pop()
try:
yield next(item)
except StopIteration:
pass
else:
push(item)
def roundrobin_rotate(*iterables):
" >> roundrobin('ABC', 'D', 'EF') --> A D E B F C"
items = deque(iter(x) for x in iterables)
while items:
try:
yield next(items[0])
except StopIteration:
items.popleft()
else:
items.rotate(-1)
funcs = [roundrobin, roundrobin_stable, roundrobin_rotate]
@pytest.mark.parametrize('func', funcs)
def test_func(func):
assert ''.join(func('ABC', 'D', 'EF')) == 'ADEBFC'
def time_it(number=100):
import timeit
setup = (
'import random;'
'params = [range(x) for x in range(100)];'
'random.shuffle(params);'
'from __main__ import {name} as func'
)
stmt = 'list(func(*params))'
for func in funcs:
print(func.__name__, timeit.Timer(
setup=setup.format(name=func.__name__),
stmt=stmt).timeit(number=number))
def loop(func, params):
for i in range(20):
list(func(*params))
def profile_it():
params = [range(x) for x in range(100)];
import profile
for func in funcs:
print(func.__name__)
profiler = profile.Profile()
profiler.runcall(loop, func, params)
profiler.print_stats()
if __name__ == '__main__':
time_it()
profile_it()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment