summaryrefslogtreecommitdiff
path: root/Demos/benchmarks/coroutines.py
blob: 007c880f4bb76bbaec12679574b09ac9e47a4101 (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
76
77
78
79
80
81
#!/usr/bin/python3
# cython: language_level=3
# micro benchmarks for coroutines

COUNT = 100000

import cython


async def done(n):
    return n


@cython.locals(N=cython.Py_ssize_t)
async def count_to(N):
    count = 0
    for i in range(N):
        count += await done(i)
    return count


async def await_all(*coroutines):
    count = 0
    for coro in coroutines:
        count += await coro
    return count


@cython.locals(N=cython.Py_ssize_t)
def bm_await_nested(N):
    return await_all(
        count_to(N),
        await_all(
            count_to(N),
            await_all(*[count_to(COUNT // i) for i in range(1, N+1)]),
            count_to(N)),
        count_to(N))


def await_one(coro):
    a = coro.__await__()
    try:
        while True:
            await_one(next(a))
    except StopIteration as exc:
        result = exc.args[0] if exc.args else None
    else:
        result = 0
    return result


def time(fn, *args):
    from time import time
    begin = time()
    result = await_one(fn(*args))
    end = time()
    return result, end-begin


def benchmark(N):
    times = []
    for _ in range(N):
        result, t = time(bm_await_nested, 1000)
        times.append(t)
        assert result == 8221043302, result
    return times


main = benchmark

if __name__ == "__main__":
    import optparse
    parser = optparse.OptionParser(
        usage="%prog [options]",
        description="Micro benchmarks for generators.")

    import util
    util.add_standard_options_to(parser)
    options, args = parser.parse_args()

    util.run_benchmark(options, options.num_runs, benchmark)