88 lines
2.4 KiB
Python
Executable File
88 lines
2.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# A simple benchmark of tornado's HTTP stack.
|
|
# Requires 'ab' to be installed.
|
|
#
|
|
# Running without profiling:
|
|
# demos/benchmark/benchmark.py
|
|
# demos/benchmark/benchmark.py --quiet --num_runs=5|grep "Requests per second"
|
|
#
|
|
# Running with profiling:
|
|
#
|
|
# python -m cProfile -o /tmp/prof demos/benchmark/benchmark.py
|
|
# python -m pstats /tmp/prof
|
|
# % sort time
|
|
# % stats 20
|
|
|
|
from tornado.ioloop import IOLoop
|
|
from tornado.options import define, options, parse_command_line
|
|
from tornado.web import RequestHandler, Application
|
|
|
|
import random
|
|
import signal
|
|
import subprocess
|
|
|
|
try:
|
|
xrange
|
|
except NameError:
|
|
xrange = range
|
|
|
|
# choose a random port to avoid colliding with TIME_WAIT sockets left over
|
|
# from previous runs.
|
|
define("min_port", type=int, default=8000)
|
|
define("max_port", type=int, default=9000)
|
|
|
|
# Increasing --n without --keepalive will eventually run into problems
|
|
# due to TIME_WAIT sockets
|
|
define("n", type=int, default=15000)
|
|
define("c", type=int, default=25)
|
|
define("keepalive", type=bool, default=False)
|
|
define("quiet", type=bool, default=False)
|
|
|
|
# Repeat the entire benchmark this many times (on different ports)
|
|
# This gives JITs time to warm up, etc. Pypy needs 3-5 runs at
|
|
# --n=15000 for its JIT to reach full effectiveness
|
|
define("num_runs", type=int, default=1)
|
|
|
|
define("ioloop", type=str, default=None)
|
|
|
|
class RootHandler(RequestHandler):
|
|
def get(self):
|
|
self.write("Hello, world")
|
|
|
|
def _log(self):
|
|
pass
|
|
|
|
def handle_sigchld(sig, frame):
|
|
IOLoop.instance().add_callback_from_signal(IOLoop.instance().stop)
|
|
|
|
def main():
|
|
parse_command_line()
|
|
if options.ioloop:
|
|
IOLoop.configure(options.ioloop)
|
|
for i in xrange(options.num_runs):
|
|
run()
|
|
|
|
def run():
|
|
app = Application([("/", RootHandler)])
|
|
port = random.randrange(options.min_port, options.max_port)
|
|
app.listen(port, address='127.0.0.1')
|
|
signal.signal(signal.SIGCHLD, handle_sigchld)
|
|
args = ["ab"]
|
|
args.extend(["-n", str(options.n)])
|
|
args.extend(["-c", str(options.c)])
|
|
if options.keepalive:
|
|
args.append("-k")
|
|
if options.quiet:
|
|
# just stops the progress messages printed to stderr
|
|
args.append("-q")
|
|
args.append("http://127.0.0.1:%d/" % port)
|
|
subprocess.Popen(args)
|
|
IOLoop.instance().start()
|
|
IOLoop.instance().close()
|
|
del IOLoop._instance
|
|
assert not IOLoop.initialized()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|