76 lines
2.2 KiB
Python
76 lines
2.2 KiB
Python
|
#!/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()
|