Created
July 1, 2013 14:42
-
-
Save temoto/5901427 to your computer and use it in GitHub Desktop.
Eventlet micro benchmark try/except or with handling of timeouts.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import eventlet | |
from eventlet.timeout import Timeout | |
import gc | |
import sys | |
import time | |
def do_with(tt, ts): | |
ok = False | |
with Timeout(tt, False): | |
eventlet.sleep(ts) | |
ok = True | |
return ok | |
def do_try(tt, ts): | |
t = Timeout(tt) | |
try: | |
eventlet.sleep(ts) | |
except Timeout, et: | |
if et is t: | |
return False | |
raise | |
finally: | |
t.cancel() | |
return True | |
def timeit_step(f, args, expected, n): | |
gc.disable() | |
try: | |
t1 = time.time() | |
for _ in xrange(n): | |
r = f(*args) | |
assert r == expected | |
t2 = time.time() | |
finally: | |
gc.enable() | |
gc.collect() | |
d = t2 - t1 | |
return d | |
def timeit(f, args, expected, min_time=1, runs=3, tag=''): | |
d = None | |
n = 1 | |
# tune n | |
for _ in xrange(20): | |
d = timeit_step(f, args, expected, n) | |
if d * 1000 <= min_time: | |
n *= 1000 | |
elif d * 10 <= min_time: | |
n *= 10 | |
elif d <= min_time: | |
n *= 2 | |
else: | |
break | |
best = None | |
for _ in xrange(runs): | |
d = timeit_step(f, args, expected, n) | |
if best is None or d < best: | |
best = d | |
best_call = best / n | |
ops = 1. / best_call | |
result = { | |
'call': best_call, | |
'n': n, | |
'ops': 1. / best_call, | |
'total': best, | |
'text': '{tag:19s} {d} us {ops:.3f} op/s'.format( | |
tag=tag, | |
d=int(best_call * 1e6), | |
ops=ops, | |
), | |
} | |
return result | |
def main(): | |
args_pass = (1, 0.00001) | |
args_timeout = (0.00001, 0.00001) | |
t1 = timeit(do_try, args_pass, True, tag='pass') | |
t2 = timeit(do_try, args_timeout, False, tag='timeout') | |
tops = t1['ops'] + t2['ops'] | |
print 'try' | |
print ' ' + t1['text'] | |
print ' ' + t2['text'] | |
print ' sum: {0:.3f} op/s'.format(tops) | |
w1 = timeit(do_with, args_pass, True, tag='pass') | |
w2 = timeit(do_with, args_timeout, False, tag='timeout') | |
wops = w1['ops'] + w2['ops'] | |
print 'with' | |
print ' ' + w1['text'] | |
print ' ' + w2['text'] | |
print ' sum: {0:.3f} op/s'.format(wops) | |
print 'Diff try/with: {0:.1%}'.format(float(tops - wops) / wops) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The difference on my netbook is just 3.2% (which I'd say is pretty small) and actually in the advantage of try, certainly if there's no timeout. This is entirely in line with what I'd expect.
BTW, any reason you're not using the timeit module from the stdlib?