]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Add a stack_context benchmark.
authorBen Darnell <ben@bendarnell.com>
Sun, 26 May 2013 18:15:12 +0000 (14:15 -0400)
committerBen Darnell <ben@bendarnell.com>
Sun, 26 May 2013 18:15:12 +0000 (14:15 -0400)
demos/benchmark/stack_context_benchmark.py [new file with mode: 0755]

diff --git a/demos/benchmark/stack_context_benchmark.py b/demos/benchmark/stack_context_benchmark.py
new file mode 100755 (executable)
index 0000000..57c7dd2
--- /dev/null
@@ -0,0 +1,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()