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
|
#!/usr/bin/env python
"""Benchmark for stack_context functionality."""
import collections
import contextlib
import functools
import subprocess
import sys
from tornado import stack_context
class Benchmark(object):
def enter_exit(self, count):
"""Measures the overhead of the nested "with" statements
when using many contexts.
"""
if count < 0:
return
with self.make_context():
self.enter_exit(count - 1)
def call_wrapped(self, count):
"""Wraps and calls a function at each level of stack depth
to measure the overhead of the wrapped function.
"""
# This queue is analogous to IOLoop.add_callback, but lets us
# benchmark the stack_context in isolation without system call
# overhead.
queue = collections.deque()
self.call_wrapped_inner(queue, count)
while queue:
queue.popleft()()
def call_wrapped_inner(self, queue, count):
if count < 0:
return
with self.make_context():
queue.append(stack_context.wrap(
functools.partial(self.call_wrapped_inner, queue, count - 1)))
class StackBenchmark(Benchmark):
def make_context(self):
return stack_context.StackContext(self.__context)
@contextlib.contextmanager
def __context(self):
yield
class ExceptionBenchmark(Benchmark):
def make_context(self):
return stack_context.ExceptionStackContext(self.__handle_exception)
def __handle_exception(self, typ, value, tb):
pass
def main():
base_cmd = [
sys.executable, '-m', 'timeit', '-s',
'from stack_context_benchmark import StackBenchmark, ExceptionBenchmark']
cmds = [
'StackBenchmark().enter_exit(50)',
'StackBenchmark().call_wrapped(50)',
'StackBenchmark().enter_exit(500)',
'StackBenchmark().call_wrapped(500)',
'ExceptionBenchmark().enter_exit(50)',
'ExceptionBenchmark().call_wrapped(50)',
'ExceptionBenchmark().enter_exit(500)',
'ExceptionBenchmark().call_wrapped(500)',
]
for cmd in cmds:
print cmd
subprocess.check_call(base_cmd + [cmd])
if __name__ == '__main__':
main()
|