Added debug control over exceptions in greenpool, benchmarks directory.
This commit is contained in:
24
benchmarks/__init__.py
Normal file
24
benchmarks/__init__.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import gc
|
||||||
|
import timeit
|
||||||
|
import random
|
||||||
|
|
||||||
|
def measure_best(repeat, iters,
|
||||||
|
common_setup='pass',
|
||||||
|
common_cleanup='pass',
|
||||||
|
*funcs):
|
||||||
|
funcs = list(funcs)
|
||||||
|
results = dict([(f,[]) for f in funcs])
|
||||||
|
|
||||||
|
for i in xrange(repeat):
|
||||||
|
random.shuffle(funcs)
|
||||||
|
for func in funcs:
|
||||||
|
gc.collect()
|
||||||
|
t = timeit.Timer(func, setup=common_setup)
|
||||||
|
results[func].append(t.timeit(iters))
|
||||||
|
common_cleanup()
|
||||||
|
|
||||||
|
best_results = {}
|
||||||
|
for func, times in results.iteritems():
|
||||||
|
best_results[func] = min(times)
|
||||||
|
return best_results
|
||||||
|
|
100
benchmarks/localhost_socket.py
Normal file
100
benchmarks/localhost_socket.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
"""Benchmark evaluating eventlet's performance at speaking to itself over a localhost socket."""
|
||||||
|
|
||||||
|
import time
|
||||||
|
import benchmarks
|
||||||
|
|
||||||
|
BYTES=1000
|
||||||
|
SIZE=1
|
||||||
|
CONCURRENCY=50
|
||||||
|
|
||||||
|
def reader(sock):
|
||||||
|
expect = BYTES
|
||||||
|
while expect > 0:
|
||||||
|
d = sock.recv(min(expect, SIZE))
|
||||||
|
expect -= len(d)
|
||||||
|
|
||||||
|
def writer(addr, socket_impl):
|
||||||
|
sock = socket_impl(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.connect(addr)
|
||||||
|
sent = 0
|
||||||
|
while sent < BYTES:
|
||||||
|
d = 'xy' * (max(min(SIZE/2, BYTES-sent), 1))
|
||||||
|
sock.sendall(d)
|
||||||
|
sent += len(d)
|
||||||
|
|
||||||
|
|
||||||
|
def green_accepter(server_sock, pool):
|
||||||
|
for i in xrange(CONCURRENCY):
|
||||||
|
sock, addr = server_sock.accept()
|
||||||
|
pool.spawn_n(reader, sock)
|
||||||
|
|
||||||
|
def heavy_accepter(server_sock, pool):
|
||||||
|
for i in xrange(CONCURRENCY):
|
||||||
|
sock, addr = server_sock.accept()
|
||||||
|
t = threading.Thread(None, reader, "reader thread", (sock,))
|
||||||
|
t.start()
|
||||||
|
pool.append(t)
|
||||||
|
|
||||||
|
import eventlet.green.socket
|
||||||
|
import eventlet
|
||||||
|
|
||||||
|
from eventlet import debug
|
||||||
|
debug.hub_exceptions(True)
|
||||||
|
|
||||||
|
def launch_green_threads():
|
||||||
|
pool = eventlet.GreenPool(CONCURRENCY * 2 + 1)
|
||||||
|
server_sock = eventlet.green.socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
server_sock.bind(('localhost', 0))
|
||||||
|
server_sock.listen(50)
|
||||||
|
addr = ('localhost', server_sock.getsockname()[1])
|
||||||
|
pool.spawn_n(green_accepter, server_sock, pool)
|
||||||
|
for i in xrange(CONCURRENCY):
|
||||||
|
pool.spawn_n(writer, addr, eventlet.green.socket.socket)
|
||||||
|
pool.waitall()
|
||||||
|
|
||||||
|
import threading
|
||||||
|
import socket
|
||||||
|
|
||||||
|
def launch_heavy_threads():
|
||||||
|
threads = []
|
||||||
|
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
server_sock.bind(('localhost', 0))
|
||||||
|
server_sock.listen(50)
|
||||||
|
addr = ('localhost', server_sock.getsockname()[1])
|
||||||
|
accepter_thread = threading.Thread(None, heavy_accepter, "accepter thread", (server_sock, threads))
|
||||||
|
accepter_thread.start()
|
||||||
|
threads.append(accepter_thread)
|
||||||
|
for i in xrange(CONCURRENCY):
|
||||||
|
client_thread = threading.Thread(None, writer, "writer thread", (addr, socket.socket))
|
||||||
|
client_thread.start()
|
||||||
|
threads.append(client_thread)
|
||||||
|
for t in threads:
|
||||||
|
t.join()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import optparse
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
parser.add_option('--compare-threading', action='store_true', dest='threading', default=False)
|
||||||
|
parser.add_option('-b', '--bytes', type='int', dest='bytes',
|
||||||
|
default=BYTES)
|
||||||
|
parser.add_option('-s', '--size', type='int', dest='size',
|
||||||
|
default=SIZE)
|
||||||
|
parser.add_option('-c', '--concurrency', type='int', dest='concurrency',
|
||||||
|
default=CONCURRENCY)
|
||||||
|
|
||||||
|
opts, args = parser.parse_args()
|
||||||
|
BYTES=opts.bytes
|
||||||
|
SIZE=opts.size
|
||||||
|
CONCURRENCY=opts.concurrency
|
||||||
|
|
||||||
|
funcs = [launch_green_threads]
|
||||||
|
if opts.threading:
|
||||||
|
funcs = [launch_green_threads, launch_heavy_threads]
|
||||||
|
results = benchmarks.measure_best(3, 3,
|
||||||
|
lambda: None, lambda: None,
|
||||||
|
*funcs)
|
||||||
|
print "green:", results[launch_green_threads]
|
||||||
|
if opts.threading:
|
||||||
|
print "threads:", results[launch_heavy_threads]
|
||||||
|
print "%", (results[launch_green_threads]-results[launch_heavy_threads])/results[launch_heavy_threads] * 100
|
56
benchmarks/spawn.py
Normal file
56
benchmarks/spawn.py
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
"""Compare spawn to spawn_n"""
|
||||||
|
|
||||||
|
import eventlet
|
||||||
|
import benchmarks
|
||||||
|
|
||||||
|
def dummy(i=None):
|
||||||
|
return i
|
||||||
|
|
||||||
|
def run_spawn():
|
||||||
|
eventlet.spawn(dummy, 1)
|
||||||
|
|
||||||
|
def run_spawn_n():
|
||||||
|
eventlet.spawn_n(dummy, 1)
|
||||||
|
|
||||||
|
def run_spawn_n_kw():
|
||||||
|
eventlet.spawn_n(dummy, i=1)
|
||||||
|
|
||||||
|
def cleanup():
|
||||||
|
eventlet.sleep(0.2)
|
||||||
|
|
||||||
|
iters = 10000
|
||||||
|
best = benchmarks.measure_best(5, iters,
|
||||||
|
'pass',
|
||||||
|
cleanup,
|
||||||
|
run_spawn_n,
|
||||||
|
run_spawn,
|
||||||
|
run_spawn_n_kw)
|
||||||
|
print "eventlet.spawn", best[run_spawn]
|
||||||
|
print "eventlet.spawn_n", best[run_spawn_n]
|
||||||
|
print "eventlet.spawn_n(**kw)", best[run_spawn_n_kw]
|
||||||
|
print "%% %0.1f" % ((best[run_spawn]-best[run_spawn_n])/best[run_spawn_n] * 100)
|
||||||
|
|
||||||
|
pool = None
|
||||||
|
def setup():
|
||||||
|
global pool
|
||||||
|
pool = eventlet.GreenPool(iters)
|
||||||
|
|
||||||
|
def run_pool_spawn():
|
||||||
|
pool.spawn(dummy, 1)
|
||||||
|
|
||||||
|
def run_pool_spawn_n():
|
||||||
|
pool.spawn_n(dummy, 1)
|
||||||
|
|
||||||
|
def cleanup_pool():
|
||||||
|
pool.waitall()
|
||||||
|
|
||||||
|
|
||||||
|
best = benchmarks.measure_best(3, iters,
|
||||||
|
setup,
|
||||||
|
cleanup_pool,
|
||||||
|
run_pool_spawn,
|
||||||
|
run_pool_spawn_n,
|
||||||
|
)
|
||||||
|
print "eventlet.GreenPool.spawn", best[run_pool_spawn]
|
||||||
|
print "eventlet.GreenPool.spawn_n", best[run_pool_spawn_n]
|
||||||
|
print "%% %0.1f" % ((best[run_pool_spawn]-best[run_pool_spawn_n])/best[run_pool_spawn_n] * 100)
|
@@ -92,6 +92,8 @@ def hub_exceptions(state):
|
|||||||
"""
|
"""
|
||||||
from eventlet import hubs
|
from eventlet import hubs
|
||||||
hubs.get_hub().set_timer_exceptions(state)
|
hubs.get_hub().set_timer_exceptions(state)
|
||||||
|
from eventlet import greenpool
|
||||||
|
greenpool.DEBUG = state
|
||||||
|
|
||||||
def tpool_exceptions(state):
|
def tpool_exceptions(state):
|
||||||
"""Toggles whether tpool itself prints exceptions that are raised from
|
"""Toggles whether tpool itself prints exceptions that are raised from
|
||||||
|
@@ -8,6 +8,8 @@ from eventlet import semaphore
|
|||||||
from eventlet.support import greenlets as greenlet
|
from eventlet.support import greenlets as greenlet
|
||||||
|
|
||||||
__all__ = ['GreenPool', 'GreenPile']
|
__all__ = ['GreenPool', 'GreenPile']
|
||||||
|
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
next
|
next
|
||||||
@@ -88,9 +90,8 @@ class GreenPool(object):
|
|||||||
except (KeyboardInterrupt, SystemExit, greenlet.GreenletExit):
|
except (KeyboardInterrupt, SystemExit, greenlet.GreenletExit):
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
# TODO control this with debug module
|
if DEBUG:
|
||||||
#traceback.print_exc()
|
traceback.print_exc()
|
||||||
pass
|
|
||||||
finally:
|
finally:
|
||||||
if coro is None:
|
if coro is None:
|
||||||
return
|
return
|
||||||
|
Reference in New Issue
Block a user