Commit 7a0a9585 authored by Jason Madden's avatar Jason Madden

More socket benchmarks [skip ci]

We're more competitive using a forked process:

.....................
gevent socketpair sendall greenlet: Mean +- std dev: 256 ms +- 6 ms
.....................
native socketpair sendall thread: Mean +- std dev: 44.4 ms +- 1.5 ms
.....................
WARNING: the benchmark result may be unstable
* the standard deviation (7.31 ms) is 13% of the mean (57.9 ms)
* the maximum (89.0 ms) is 54% greater than the mean (57.9 ms)

Try to rerun the benchmark with more runs, values and/or loops.
Run 'python -m perf system tune' command to reduce the system jitter.
Use perf stats, perf dump and perf hist to analyze results.
Use --quiet option to hide these warnings.

gevent socketpair sendall fork: Mean +- std dev: 57.9 ms +- 7.3 ms
.....................
native socketpair sendall fork: Mean +- std dev: 44.6 ms +- 2.0 ms
.....................
native udp sendto: Mean +- std dev: 30.6 ms +- 1.1 ms
.....................
gevent udp sendto: Mean +- std dev: 37.5 ms +- 2.7 ms

(python 3.7)
parent 6e2ab023
...@@ -4,6 +4,10 @@ Basic socket benchmarks. ...@@ -4,6 +4,10 @@ Basic socket benchmarks.
""" """
from __future__ import print_function, division, absolute_import from __future__ import print_function, division, absolute_import
import os
import sys
import perf import perf
import gevent import gevent
...@@ -60,6 +64,23 @@ def bench_gevent_udp(loops): ...@@ -60,6 +64,23 @@ def bench_gevent_udp(loops):
finally: finally:
conn.close() conn.close()
def _do_sendall(loops, send, recv):
for s in send, recv:
os.set_inheritable(s.fileno(), True)
pid = os.fork()
if not pid:
send.close()
recvall(recv, None)
recv.close()
sys.exit()
return 0
else:
try:
return _sendall(loops, send, BIG_DATA)
finally:
send.close()
recv.close()
def bench_native_thread_default_socketpair(loops): def bench_native_thread_default_socketpair(loops):
send, recv = socket.socketpair() send, recv = socket.socketpair()
t = threading.Thread(target=recvall, args=(recv, None)) t = threading.Thread(target=recvall, args=(recv, None))
...@@ -71,20 +92,53 @@ def bench_native_thread_default_socketpair(loops): ...@@ -71,20 +92,53 @@ def bench_native_thread_default_socketpair(loops):
def bench_gevent_greenlet_default_socketpair(loops): def bench_gevent_greenlet_default_socketpair(loops):
send, recv = gsocket.socketpair() send, recv = gsocket.socketpair()
gevent.spawn(recvall, recv, None) gevent.spawn(recvall, recv, None)
return _sendall(loops, send, BIG_DATA) return _sendall(loops, send, BIG_DATA)
def bench_gevent_forked_socketpair(loops):
send, recv = gsocket.socketpair()
return _do_sendall(loops, send, recv)
def bench_native_forked_socketpair(loops):
send, recv = socket.socketpair()
return _do_sendall(loops, send, recv)
def main(): def main():
if '--profile' in sys.argv:
import cProfile
import pstats
import io
pr = cProfile.Profile()
pr.enable()
for _ in range(2):
bench_gevent_forked_socketpair(2)
pr.disable()
s = io.StringIO()
sortby = 'cumulative'
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print(s.getvalue())
return
runner = perf.Runner() runner = perf.Runner()
runner.bench_time_func( runner.bench_time_func(
'native socketpair sendall', 'gevent socketpair sendall greenlet',
bench_gevent_greenlet_default_socketpair,
inner_loops=N)
runner.bench_time_func(
'native socketpair sendall thread',
bench_native_thread_default_socketpair, bench_native_thread_default_socketpair,
inner_loops=N) inner_loops=N)
runner.bench_time_func( runner.bench_time_func(
'gevent socketpair sendall', 'gevent socketpair sendall fork',
bench_gevent_greenlet_default_socketpair, bench_gevent_forked_socketpair,
inner_loops=N)
runner.bench_time_func(
'native socketpair sendall fork',
bench_native_forked_socketpair,
inner_loops=N) inner_loops=N)
runner.bench_time_func( runner.bench_time_func(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment