Hello All,<br><br>First of all thanks for all the pointers in the #twisted about twisted.web being able to use threadpool. Here's the benchmark between cherryPy 3.0 and twisted.web that I promised. I hope this could serve as a reference in the future.<br>
<br><b>Testing parameters:</b><br>- Office PC: Intel(R) Pentium(R) D CPU 2.80GHz with 1GB RAM<br>- Apache bench set to 500 concurrent attempts within 30 secs<br>- LinuxMint Elyssa/Python 2.5.2/Twisted 2.5<br>- Twisted using SelectReactor<br>
- Webservers just returning "Hello!" after some mathematical calculation:<br> <br> result = 0<br> for i in range(random.randint(100, 300)):<br> angle = math.radians(random.randint(0, 45))<br>
result += math.tanh(angle)/math.cosh(angle)<br><br clear="all"><b><br>CherryPy Results:</b><br>Concurrency Level: 500<br>Time taken for tests: 30.1441 seconds<br>Complete requests: <b>6421</b><br>
Failed requests: 0<br>
Write errors: 0<br>Total transferred: 834990 bytes<br>HTML transferred: 38538 bytes<br>Requests per second: 214.02 [#/sec] (mean)<br>Time per request: 2336.197 [ms] (mean)<br>Time per request: 4.672 [ms] (mean, across all concurrent requests)<br>
Transfer rate: 27.17 [Kbytes/sec] received<br><b><br>twisted-web Results (no threading):</b><br>Concurrency Level: 500<br>Time taken for tests: 30.35509 seconds<br>Complete requests: <b>10051</b><br>
Failed requests: 0<br>
Write errors: 0<br>Total transferred: 502600 bytes<br>HTML transferred: 60312 bytes<br>Requests per second: 334.64 [#/sec] (mean)<br>Time per request: 1494.155 [ms] (mean)<br>Time per request: 2.988 [ms] (mean, across all concurrent requests)<br>
Transfer rate: 16.31 [Kbytes/sec] received<br><br><br><b>twisted-web Results (with threading, threadpool [min=100, max=400]):</b><br>Concurrency Level: 500<br>Time taken for tests: 30.16998 seconds<br>Complete requests: <b>11068</b><br>
Failed requests: 0<br>Write errors: 0<br>Total transferred: 553450 bytes<br>HTML transferred: 66414 bytes<br>Requests per second: 368.72 [#/sec] (mean)<br>Time per request: 1356.026 [ms] (mean)<br>
Time per request: 2.712 [ms] (mean, across all concurrent requests)<br>Transfer rate: 17.99 [Kbytes/sec] received<br><br><br><b>Source Listing (using Twisted):<br></b><br><font size="1">#!/usr/bin/python<br>
from twisted.internet import reactor<br>from twisted.web import http<br>from twisted.python.threadpool import ThreadPool<br>import random, math, sys<br><br>class HTTPProtocol(http.Request):<br> def process(self):<br> def process_finish():<br>
result = 0<br> for i in range(random.randint(100, 300)):<br> angle = math.radians(random.randint(0, 45))<br> result += math.tanh(angle)/math.cosh(angle)<br> self.setHeader('Content-Type', 'text/html')<br>
self.write("Hello!")<br> self.finish()<br> if self.channel.factory.app.threads_enabled:<br> print("Using threads")<br> reactor.callFromThread(process_finish)<br>
else:<br> print("Not using threads")<br> process_finish()<br> <br>class HTTPChannel(http.HTTPChannel):<br> requestFactory = HTTPProtocol<br><br>class HTTPFactory(http.HTTPFactory):<br>
protocol = HTTPChannel<br> def __init__(self, app):<br> self.app = app<br><br> def start(self, port=8080):<br> reactor.listenTCP(port, self)<br><br>class BenchmarkApplication():<br> def __init__(self):<br>
self.httpfactory = None<br> self.pool = None<br> self.threads_enabled = False<br><br> def start(self):<br> try:<br> minthreads = int(sys.argv[1])<br> maxthreads = int(sys.argv[2])<br>
self.pool = ThreadPool(minthreads, maxthreads)<br> self.pool.start()<br> self.threads_enabled = True<br> print "Threads enabled: MIN:%d MAX:%d" % (minthreads, maxthreads)<br>
except Exception, e:<br> print("minthreads and maxthreads is not set or malformed. Threading will be disabled")<br> self.httpfactory = HTTPFactory(self)<br> self.httpfactory.start()<br>
return (True)<br><br> def end(self):<br> if self.pool != None:<br> self.pool.stop()<br><br>if __name__ == "__main__":<br> gba = BenchmarkApplication()<br> if gba.start():<br> reactor.run()<br>
gba.end()</font><b><br><br>Source Listing (using CherryPy):<br></b><font size="1">#!/usr/bin/python<br>import cherrypy<br>from amazilia import *<br>from amazilia import base<br>from amazilia import mysql<br>import random, math<br>
<br>class Root:<br> def index(self):<br> result = 0 <br> for i in range(random.randint(100, 300)):<br> angle = math.radians(random.randint(0, 45))<br> result += math.tanh(angle)/math.cosh(angle)<br>
return "Hello!"<br> index.exposed = True<br><br>root = Root()<br>cherrypy.quickstart(root)</font><b><br><br><br></b>I haven't had much time to tinker with CherryPy. Threre might be some ways to increase its performance. :)<br>
<br>---<br>Alvin <br>-- <br><a href="http://www.alvinatorsplayground.blogspot.com/" target="_blank">http://www.alvinatorsplayground.blogspot.com/</a><br>