2

I wrote two simple apps, one is raw wsgi application like below while another one is built with Flask, and both run on gevent wsgi server.
When there are no network connections in the app, as I expected, raw wsgi app is more faster than the flask app, but when there are some network connections in the app, raw wsgi app is way more slower than the flask app.

raw

import json
from gevent import monkey
monkey.patch_all() # monkey patch for both apps

import pymysql
conn = pymysql.connect(host=HOST,port=PORT,...,cursorclass=pymysql.cursors.DictCursor) 

import requests

def application(environ, start_response):
    # database connection
    cur = conn.cursor()
    cur.execute('select * from food')
    res = cur.fetchall()

    # requests
    resp = requests.get('http://www.baidu.com')

    start_response('200 OK', [('Content-Type', 'application')])
    return json.dumps(res)
    # return resp.content
from gevent.wsgi import WSGIServer
http_server = WSGIServer(('', 8080), application)
http_server.serve_forever()

flask

from gevent import monkey
monkey.patch_all()
import json
from flask import Flask
app = Flask(__name__)

conn = pymysql.connect(host=HOST,port=PORT,...,cursorclass=pymysql.cursors.DictCursor)
@app.route('/')
def index():
    # database connection
    cur = conn.cursor()
    cur.execute('select * from food')
    res = cur.fetchall()

    # requests
    resp = requests.get('http://www.baidu.com')
    return json.dumps(res), 200
from gevent.wsgi import WSGIServer
http_server = WSGIServer(('', 8080), app)
http_server.serve_forever()

I'm using ab to do the benchmark test:

$ ab -c10 -n10000 http://127.0.0.1:8080/

here is the raw wsgi app result:

    Concurrency Level:      10
    Time taken for tests:   306.216 seconds
    Requests per second:    1.52 [#/sec] (mean)
    Time per request:       6585.299 [ms] (mean)
    Time per request:       658.530 [ms] (mean, across all concurrent requests)

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.4      0       7
    Processing:  1084 6499 3050.3   5951   15963
    Waiting:       96 5222 3051.4   4577   15096
    Total:       1085 6500 3050.2   5951   15963

    Percentage of the requests served within a certain time (ms)
      50%   5938
      66%   7584
      75%   8597
      80%   9186
      90%  10829
      95%  12033
      98%  13209
      99%  14722
     100%  15963 (longest request)

and flask app's:

    Concurrency Level:      10
    Time taken for tests:   19.909 seconds
    Requests per second:    502.28 [#/sec] (mean)
    Time per request:       19.909 [ms] (mean)
    Time per request:       1.991 [ms] (mean, across all concurrent requests)

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.0      0       2
    Processing:     3   20   9.0     19      87
    Waiting:        2   20   8.9     19      86
    Total:          3   20   9.0     19      87

    Percentage of the requests served within a certain time (ms)
      50%     19
      66%     23
      75%     25
      80%     27
      90%     31
      95%     36
      98%     41
      99%     45
     100%     87 (longest request)

So I'm wondering what did flask do and what can I do to be more faster using a simple wsgi app without a framework?

jerrypy
  • 139
  • 1
  • 2
  • 14
  • 3
    Don't use ``requests.get('http://www.baidu.com')`` for bench marking for these apps! Both of these apps waste most of the time on Network IO. So it does not implicate anything. – Kane Blueriver Nov 21 '15 at 15:06
  • @kxxoling okay, but comment that I got the same result. – jerrypy Nov 22 '15 at 01:49
  • Have you just commented ``return resp.content``? I think you should also comment the assignment part. – Kane Blueriver Nov 22 '15 at 02:05
  • On the other way, database fetch is also an IO action which would affect the result in some way. – Kane Blueriver Nov 22 '15 at 02:07
  • Actually I wrote two tests, one does db connection, one does requests, I wrote them together in the above code, just want to simplify the questions, sorry it confused you guys. – jerrypy Nov 22 '15 at 02:08

1 Answers1

1

I think your question does not exist. The biggest error you made is introducing IO part(Network IO and Disk IO) which have no relation with the performance of web frameworks.

To prove this, I simplified your demo to these:

import json
from gevent import monkey
monkey.patch_all() # monkey patch for both apps

def application(environ, start_response):    
    res = dict(hello='world')

    start_response('200 OK', [('Content-Type', 'application')])
    return json.dumps(res)

from gevent.wsgi import WSGIServer
http_server = WSGIServer(('', 8088), application)
http_server.serve_forever()

and:

from gevent import monkey
monkey.patch_all()
import json
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    res = dict(hello='world')
    return json.dumps(res), 200

from gevent.wsgi import WSGIServer

http_server = WSGIServer(('', 8088), app)
http_server.serve_forever()

My result of raw WSGI is:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       5
Processing:     1    5   0.7      5      23
Waiting:        1    5   0.7      5      23
Total:          1    6   0.7      5      24
WARNING: The median and mean for the total time are not within a normal deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%      5
  66%      6
  75%      6
  80%      6
  90%      6
  95%      6
  98%      7
  99%      8
 100%     24 (longest request)

For Flask it is:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       1
Processing:     1    6   0.6      6      11
Waiting:        1    6   0.6      6      11
Total:          2    6   0.6      6      11

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      6
  75%      6
  80%      6
  90%      7
  95%      7
  98%      7
  99%      8
 100%     11 (longest request)

Ignoring the longest 1% requests, you can find raw WSGI is 20% time faster than Flask which seems reasonable.

Kane Blueriver
  • 4,170
  • 4
  • 29
  • 48