Added debug control over exceptions in greenpool, benchmarks directory.

This commit is contained in:
Ryan Williams
2010-01-21 00:37:03 -05:00
parent 5b8acc850f
commit e60a78444c
5 changed files with 186 additions and 3 deletions

24
benchmarks/__init__.py Normal file
View 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

View 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
View 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)

View File

@@ -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

View File

@@ -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