C'est la saison d'ISUCON. ISUCON utilise habituellement le microframework typique dans chaque langage, mais Python utilise Flask pour l'instant.
Flask ressemble certainement à un microframework lors de l'écriture d'un exemple d'application simple. Cependant, structurellement, il existe de nombreux crochets et signaux, et c'est une conception lourde.
Le corps Flask combiné et Werkzeug ont une taille de dizaines de milliers de lignes. Même une simple application Hello World a des dizaines d'appels de fonction dans les coulisses.
Comme Flask, Bottle est un framework qui est multi-thread, a une pile de contexte qui utilise des threads locaux et a des extensions, mais sa structure est beaucoup plus simple que Flask. Le code source est de 3000 lignes par fichier et la surcharge du framework est environ la moitié de celle de Flask.
J'ai fait une petite mesure avec l'application Hello. Sur MacBook Air 2013 Mid (Core i5 1,3 GHz), comparez une application Hello à un seul thread et un seul processus avec wrk -t1 -c1. Python est CPython 3.4.1 et le serveur Web est Meinheld (dernière version de Github).
wsgi:
$ wrk -t1 -c1 http://localhost:6000/
Running 10s test @ http://localhost:6000/
1 threads and 1 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 118.89us 46.59us 0.99ms 91.40%
Req/Sec 7.57k 622.67 9.90k 67.44%
71708 requests in 10.00s, 11.08MB read
Requests/sec: 7170.95
Transfer/sec: 1.11MB
Bottle:
$ wrk -t1 -c1 http://localhost:6000/
Running 10s test @ http://localhost:6000/
1 threads and 1 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 221.92us 678.78us 18.72ms 99.81%
Req/Sec 4.86k 418.08 6.44k 78.08%
46110 requests in 10.00s, 7.74MB read
Requests/sec: 4611.09
Transfer/sec: 792.53KB
Flask:
$ wrk -t1 -c1 http://localhost:6000/
Running 10s test @ http://localhost:6000/
1 threads and 1 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 476.59us 134.74us 1.71ms 79.35%
Req/Sec 2.11k 194.96 3.10k 65.86%
19967 requests in 10.00s, 3.35MB read
Requests/sec: 1996.71
Transfer/sec: 343.18KB
En regardant la différence de latence moyenne, environ 100 μs pour Bottle et environ 350 μs pour Flask sont des frais généraux pour le wsgi brut, ce qui représente plus du double de la performance totale.
Bottle prend également en charge les modèles Jinja, donc même si votre application initiale était Flask, vous devriez être raisonnablement facile de passer à Bottle. Dans les cas où il y a beaucoup de chemins qui ne font que mettre en cache la partie HTML et recoller les données de Memcached, les performances de cette partie de base devraient être une différence non négligeable.
Enfin, je mettrai le code source mesuré. Essayez-le.
import flask
import bottle
app = flask.Flask(__name__)
bottle_app = bottle.app()
@bottle_app.route('/')
@app.route('/')
def index():
return b"Hello, World"
def wsgi(env, start):
c = b"Hello, World"
start("200 OK", [('Content-Type', 'text/plain'), ('Content-Length', str(len(c)))])
return [c]
#méthode de départ
# Flask: gunicorn -k meinheld.gmeinheld.MeinheldWorker -b :6000 app:app
# Bottle: gunicorn -k meinheld.gmeinheld.MeinheldWorker -b :6000 app:bottle_app
# wsgi: gunicorn -k meinheld.gmeinheld.MeinheldWorker -b :6000 app:wsgi
Recommended Posts