File: bench_spawn.py

package info (click to toggle)
python-gevent 24.11.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,364 kB
  • sloc: python: 138,768; ansic: 87,807; sh: 12,548; makefile: 2,379; javascript: 108
file content (230 lines) | stat: -rw-r--r-- 5,929 bytes parent folder | download | duplicates (3)
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
"""
Benchmarking spawn() performance.
"""
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

from pyperf import perf_counter
from pyperf import Runner

try:
    xrange
except NameError:
    xrange = range


N = 10000
counter = 0


def incr(**_kwargs):
    global counter
    counter += 1


def noop(_p):
    pass

class Options(object):

    # TODO: Add back an argument for that
    eventlet_hub = None

    loops = None

    def __init__(self, sleep, join, **kwargs):
        self.kwargs = kwargs
        self.sleep = sleep
        self.join = join

class Times(object):

    def __init__(self,
                 spawn_duration,
                 sleep_duration=-1,
                 join_duration=-1):
        self.spawn_duration = spawn_duration
        self.sleep_duration = sleep_duration
        self.join_duration = join_duration


def _test(spawn, sleep, options):
    global counter
    counter = 0
    before_spawn = perf_counter()
    for _ in xrange(N):
        spawn(incr, **options.kwargs)
    spawn_duration = perf_counter() - before_spawn


    if options.sleep:
        assert counter == 0, counter
        before_sleep = perf_counter()
        sleep(0)
        sleep_duration = perf_counter() - before_sleep
        assert counter == N, (counter, N)
    else:
        sleep_duration = -1


    if options.join:
        before_join = perf_counter()
        options.join()
        join_duration = perf_counter() - before_join
    else:
        join_duration = -1

    return Times(spawn_duration,
                 sleep_duration,
                 join_duration)

def test(spawn, sleep, options):
    all_times = [
        _test(spawn, sleep, options)
        for _ in xrange(options.loops)
    ]

    spawn_duration = sum(x.spawn_duration for x in all_times)
    sleep_duration = sum(x.sleep_duration for x in all_times)
    join_duration = sum(x.sleep_duration for x in all_times
                        if x != -1)

    return Times(spawn_duration, sleep_duration, join_duration)

def bench_none(options):
    from time import sleep

    options.sleep = False

    def spawn(f, **kwargs):
        return f(**kwargs)

    return test(spawn,
                sleep,
                options)


def bench_gevent(options):
    from gevent import spawn, sleep
    return test(spawn, sleep, options)


def bench_geventraw(options):
    from gevent import sleep, spawn_raw
    return test(spawn_raw, sleep, options)


def bench_geventpool(options):
    from gevent import sleep
    from gevent.pool import Pool
    p = Pool()
    if options.join:
        options.join = p.join
    times = test(p.spawn, sleep, options)
    return times


try:
    __import__('eventlet')
except ImportError:
    pass
else:
    def bench_eventlet(options):
        from eventlet import spawn, sleep
        if options.eventlet_hub is not None:
            from eventlet.hubs import use_hub
            use_hub(options.eventlet_hub)
        return test(spawn, sleep, options)


def all():
    result = [x for x in globals() if x.startswith('bench_') and x != 'bench_all']
    result.sort()
    result = [x.replace('bench_', '') for x in result]
    return result



def main(argv=None):
    import os
    import sys
    if argv is None:
        argv = sys.argv[1:]

    env_options = [
        '--inherit-environ',
        ','.join([k for k in os.environ
                  if k.startswith(('GEVENT',
                                   'PYTHON',
                                   'ZS', # experimental zodbshootout config
                                   'RS', # relstorage config
                                   'COVERAGE'))])]
    # This is a default, so put it early
    argv[0:0] = env_options

    def worker_cmd(cmd, args):
        cmd.extend(args.benchmark)

    runner = Runner(add_cmdline_args=worker_cmd)
    runner.argparser.add_argument('benchmark',
                                  nargs='*',
                                  default='all',
                                  choices=all() + ['all'])

    def spawn_time(loops, func, options):
        options.loops = loops
        times = func(options)
        return times.spawn_duration

    def sleep_time(loops, func, options):
        options.loops = loops
        times = func(options)
        return times.sleep_duration

    def join_time(loops, func, options):
        options.loops = loops
        times = func(options)
        return times.join_duration

    args = runner.parse_args(argv)

    if 'all' in args.benchmark or args.benchmark == 'all':
        args.benchmark = ['all']
        names = all()
    else:
        names = args.benchmark

    names = sorted(set(names))

    for name in names:
        runner.bench_time_func(name + ' spawn',
                               spawn_time,
                               globals()['bench_' + name],
                               Options(sleep=False, join=False),
                               inner_loops=N)

        if name != 'none':
            runner.bench_time_func(name + ' sleep',
                                   sleep_time,
                                   globals()['bench_' + name],
                                   Options(sleep=True, join=False),
                                   inner_loops=N)

    if 'geventpool' in names:
        runner.bench_time_func('geventpool join',
                               join_time,
                               bench_geventpool,
                               Options(sleep=True, join=True),
                               inner_loops=N)

    for name in names:
        runner.bench_time_func(name + ' spawn kwarg',
                               spawn_time,
                               globals()['bench_' + name],
                               Options(sleep=False, join=False, foo=1, bar='hello'),
                               inner_loops=N)


if __name__ == '__main__':
    main()