blob: f55234b9faa9dff73ca2b0d2ee8503edf9841774 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
"""Compare timing of yield-from <generator> vs. yield <future> calls."""
import gc
import time
def coroutine(n):
if n <= 0:
return 1
l = yield from coroutine(n-1)
r = yield from coroutine(n-1)
return l + 1 + r
def run_coro(depth):
t0 = time.time()
try:
g = coroutine(depth)
while True:
next(g)
except StopIteration as err:
k = err.value
t1 = time.time()
print('coro', depth, k, round(t1-t0, 6))
return t1-t0
class Future:
def __init__(self, g):
self.g = g
def wait(self):
value = None
try:
while True:
f = self.g.send(value)
f.wait()
value = f.value
except StopIteration as err:
self.value = err.value
def task(func): # Decorator
def wrapper(*args):
g = func(*args)
f = Future(g)
return f
return wrapper
@task
def oldstyle(n):
if n <= 0:
return 1
l = yield oldstyle(n-1)
r = yield oldstyle(n-1)
return l + 1 + r
def run_olds(depth):
t0 = time.time()
f = oldstyle(depth)
f.wait()
k = f.value
t1 = time.time()
print('olds', depth, k, round(t1-t0, 6))
return t1-t0
def main():
gc.disable()
for depth in range(16):
tc = run_coro(depth)
to = run_olds(depth)
if tc:
print('ratio', round(to/tc, 2))
if __name__ == '__main__':
main()
|