Почему необработанное приложение wsgi работает медленнее, чем приложение flask?

Я написал два простых приложения, одно из которых представляет собой необработанное приложение wsgi, как показано ниже, а другое создано с помощью Flask, и оба работают на сервере gevent wsgi.
Когда в приложении нет сетевых подключений, как я и ожидал, необработанное приложение wsgi работает быстрее, чем приложение flask, но когда в приложении есть некоторые сетевые подключения, необработанное приложение wsgi работает намного медленнее, чем приложение flask. .

сырой

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()

колба

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()

Я использую ab для тестов производительности:

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

вот необработанный результат приложения wsgi:

    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)

и фляжное приложение:

    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)

Итак, мне интересно, что сделал flask и что я могу сделать, чтобы работать быстрее, используя простое приложение wsgi без фреймворка?


person jerrypy    schedule 21.11.2015    source источник
comment
Не используйте requests.get('http://www.baidu.com') для бенчмаркинга этих приложений! Оба этих приложения тратят большую часть времени на сетевой ввод-вывод. Так что это ни на что не влияет.   -  person kxxoling    schedule 21.11.2015
comment
@kxxoling хорошо, но прокомментируйте, что я получил тот же результат.   -  person jerrypy    schedule 22.11.2015
comment
Вы только что прокомментировали return resp.content? Я думаю, вы должны также прокомментировать часть назначения.   -  person kxxoling    schedule 22.11.2015
comment
С другой стороны, выборка из базы данных также является действием ввода-вывода, которое каким-то образом повлияет на результат.   -  person kxxoling    schedule 22.11.2015
comment
На самом деле я написал два теста, один выполняет соединение с базой данных, другой выполняет запросы, я написал их вместе в приведенном выше коде, просто хочу упростить вопросы, извините, ребята, это вас запутало.   -  person jerrypy    schedule 22.11.2015


Ответы (1)


Я думаю, что вашего вопроса не существует. Самая большая ошибка, которую вы допустили, - это введение части ввода-вывода (сетевой ввод-вывод и дисковый ввод-вывод), которые не имеют никакого отношения к производительности веб-фреймворков.

Чтобы доказать это, я упростил вашу демонстрацию до следующего:

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()

и:

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()

Мой результат сырого WSGI:

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)

Для Flask это:

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)

Игнорируя самые длинные 1% запросов, вы можете обнаружить, что необработанный WSGI на 20% быстрее, чем Flask, что кажется разумным.

person kxxoling    schedule 22.11.2015