title: how is cherrypy working? it handls requests well compared with tornado when concurrence is low
body: <p>I carried out a test on cherrypy (using web.py as a framework) and tornado retrieving webpages from the internet.</p>
  
  <p>I have three test cases using <code>siege</code> to send requests to server (-c means number of users; -t is testing time). Code is below the test results.</p>
  
  <h2>1. web.py (cherrpy)</h2>
  
  <pre><code>  siege ip -c20 -t100s             server can handle 2747requests  
    siege ip -c200 -t30s             server can handle 1361requests
    siege ip -c500 -t30s             server can handle 170requests
  </code></pre>
  
  <h2>2. tornado synchronous</h2>
  
  <pre><code>  siege ip -c20 -t100s             server can handle 600requests  
    siege ip -c200 -t30s             server can handle 200requests
    siege ip -c500 -t30s             server can handle 116requests
  </code></pre>
  
  <h2>3. tornado asynchronous</h2>
  
  <pre><code>  siege ip -c20 -t100s             server can handle 3022requests  
    siege ip -c200 -t30s             server can handle 2259requests
    siege ip -c500 -t30s             server can handle 471requests
  </code></pre>
  
  <h2>performance analysis:</h2>
  
  <p>tornado synchronous &lt; web.py (cherrypy) &lt; tornado asynchronous</p>
  
  <h2>Question 1:</h2>
  
  <p>I know, using an asynchronous architecture can improve the performance of a web server dramatically.</p>
  
  <p>I'm curious about the difference between tornado asynchronous architecture and web.py (cherry).</p>
  
  <p>I think tornado synchronous mode handles requests one by one, but how is cherrypy working, using multiple threads? But I didn't see a large increase of memory. Cherrypy might handle multiple requests concurrently. How does it solve the blocking of a program?</p>
  
  <h2>Question 2:</h2>
  
  <p>Can I improve the performance of tornado synchronous mode without using asynchronous techniques? I think tornado can do better.</p>
  
  <h2><em><strong>Web.py code:</em></strong></h2>
  
  <pre><code>import web
  import tornado.httpclient
  urls = (
      '/(.*)', 'hello'
  )
  app = web.application(urls, globals())
  
  class hello:
      def GET(self, name):
          client = tornado.httpclient.HTTPClient()
          response=client.fetch("http://www.baidu.com/")
          return response.body
  
  if __name__ == "__main__":
      app.run()
  </code></pre>
  
  <h2><em><strong>Tornado synchronous:</em></strong></h2>
  
  <pre><code>import tornado.ioloop
  import tornado.options
  import tornado.web
  import tornado.httpclient
  from tornado.options import define, options
  define("port", default=8000, help="run on the given port", type=int)
  class IndexHandler(tornado.web.RequestHandler):
      def get(self):
          client = tornado.httpclient.HTTPClient()
          response = client.fetch("http://www.baidu.com/" )
          self.write(response.body)
  
  
  if __name__=='__main__':
      tornado.options.parse_command_line()
      app=tornado.web.Application(handlers=[(r'/',IndexHandler)])
      http_server=tornado.httpserver.HTTPServer(app)
      http_server.listen(options.port)
      tornado.ioloop.IOLoop.instance().start()
  </code></pre>
  
  <h2><em><strong>Tornado asynchronous:</em></strong></h2>
  
  <pre><code>import tornado.httpserver
  import tornado.ioloop
  import tornado.options
  import tornado.web
  import tornado.httpclient
  from tornado.options import define, options
  define("port", default=8001, help="run on the given port", type=int)
  class IndexHandler(tornado.web.RequestHandler):
      @tornado.web.asynchronous
      def get(self):
          client = tornado.httpclient.AsyncHTTPClient()
          response = client.fetch("http://www.baidu.com/" ,callback=self.on_response)
  
      def on_response(self,response):
          self.write(response.body)
          self.finish()
  
  if __name__=='__main__':
      tornado.options.parse_command_line()
      app=tornado.web.Application(handlers=[(r'/',IndexHandler)])
      http_server=tornado.httpserver.HTTPServer(app)
      http_server.listen(options.port)
      tornado.ioloop.IOLoop.instance().start()
  </code></pre>