J'ai comparé la vitesse de l'écho du framework web en langage go et du flask du framework web python

Comparez les vitesses d'exécution de golang-echo et python-flask

J'ai touché python tout le temps et je n'en ai pas été particulièrement insatisfait, mais récemment j'ai touché le golang. Python est pratique pour créer quelque chose, mais je veux avoir une idée de la vitesse à laquelle il peut être avec golang lorsque la vitesse est nécessaire, donc le cadre Web typique de golang fait écho et le cadre Web léger de python J'ai comparé des flacons pour voir à quel point les vitesses différaient.

environnement de test

Le disque dur ubuntu 16.04 construit sur vmware est normal, pas ssd. i7,memory 6GB python2.7 golang 1.6

Une application Web qui renvoie une chaîne simple

Essayez d'abord de créer une application Web simple pour vous faire une idée

Une application simple utilisant golang-echo

Tout d'abord, à partir d'une simple application Web qui utilise golang

simple_server.go



package main
import (
        "net/http"
        "github.com/labstack/echo"
        "github.com/labstack/echo/engine/standard"
)
func main() {
        e := echo.New()
        e.GET("/", func(c echo.Context) error {
                return c.String(http.StatusOK, "Hello, World!")
        })
        e.Run(standard.New(":1323"))
}

Si vous utilisez la bibliothèque d'écho avec golang, vous pouvez facilement l'écrire en tant qu'application Web qui renvoie Hello World.

Essayez de mesurer la vitesse du golang-écho

Voyons la vitesse à l'aide du banc Apache

shibacow@ubuntu:~/prog/golang/echo_test$ ab -n 100000 -c 100 http://localhost:1323/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 10000 requests
...
Completed 100000 requests
Finished 100000 requests

Server Software:
Server Hostname:        localhost
Server Port:            1323

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      100
Time taken for tests:   9.525 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      13000000 bytes
HTML transferred:       1300000 bytes
Requests per second:    10498.93 [#/sec](mean)
Time per request:       9.525 [ms](mean)
Time per request:       0.095 [ms](mean, across all concurrent requests)
Transfer rate:          1332.87 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3   2.8      2      19
Processing:     0    6   3.2      7      31
Waiting:        0    5   2.5      4      26
Total:          0    9   4.1      9      33

Percentage of the requests served within a certain time (ms)
  50%      9
  66%     11
  75%     12
  80%     13
  90%     15
  95%     17
  98%     18
  99%     19
100% 33 (longest request)

Requests per second: 10498.93 #/sec

Il semble qu'environ 10 000 req / s sortiront sans réglage.

Application simple utilisant python-flask

Ensuite, vérifiez le ballon

simple_server.py


#!/usr/bin/env python
# -*- coding:utf-8 -*-

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == '__main__':
app.run()

flask renvoie également Hello World avec ceci

benchmark python-flask

shibacow@ubuntu:~/prog/golang/echo_test$ ab -n 10000 -c 100  http://localhost:5000/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 1000 requests
...
Completed 10000 requests
Finished 10000 requests


Server Software:        Werkzeug/0.11.10
Server Hostname:        localhost
Server Port:            5000

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   8.190 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1680000 bytes
HTML transferred:       120000 bytes
Requests per second:    1220.97 [#/sec](mean)
Time per request:       81.902 [ms](mean)
Time per request:       0.819 [ms](mean, across all concurrent requests)
Transfer rate:          200.32 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       8
Processing:     2   81  12.6     81     148
Waiting:        1   81  12.5     81     148
Total:          6   81  12.2     81     148

Percentage of the requests served within a certain time (ms)
  50%     81
  66%     90
  75%     91
  80%     92
  90%     95
  95%     98
  98%    101
  99%    106
 100%    148 (longest request)

Requests per second: 1220.97 #/sec

Ne rien faire de particulier et obtenir environ 1220 req / sec

Une application Web qui se connecte à Mongodb, recherche et renvoie des résultats

S'il s'agit d'une application simple, elle sera différente du problème réel, alors connectez-vous à mongo, recherchez et renvoyez le résultat, etc. J'ai fait référence à ce site.

application web qui se connecte à mongo à l'aide de golang-echo

mgo_server.go



package main

import (
        //Système serveur
        "net/http"
        "github.com/labstack/echo"
        "github.com/labstack/echo/engine/standard"

        //système mongo
        "fmt"
        "gopkg.in/mgo.v2"
        "gopkg.in/mgo.v2/bson"

        //Moule
        "strconv"
        //"reflect"
)

//Classe d'utilisateurs
type User struct {
        Name  string `bson:"name"`
        Id int `bson:"id"`
}

func main() {
        e := echo.New()
        e.GET("/", func(c echo.Context) error {
                return c.String(http.StatusOK, "Hello, World!")
        })

        // :id, :Non trouvé si le nom ne contient pas de valeur
        e.GET("/users/id/:id", func(c echo.Context) error {

                //Besoin de convertir en nombre
                var id int
                id, _ = strconv.Atoi(c.Param("id"))

                //Soustraire DB par id
                session, _ := mgo.Dial("mongodb://localhost")
                defer session.Close()
                db := session.DB("test")

                //Obtenir l'utilisateur en spécifiant son identifiant
                var results []User
                fmt.Println(id)
                db.C("user").Find(bson.M{"id": id}).All(&results)

                fmt.Println("Results of one user: ", results)
                fmt.Println(len(results))

                if len(results) == 0 {
                        return c.String(http.StatusOK, "No user")
                }else{
                        name := results[0].Name
                        return c.String(http.StatusOK, "Hello, " + name)
                }
        })

        e.POST("/user", func(c echo.Context) error {
                return c.String(http.StatusOK, "Hello, POST user")
        })

        //Port
        e.Run(standard.New(":1323"))
}

Référence de connexion golang-echo mongo

Un benchmark de ce qui se connecte à mongodb et renvoie des résultats

shibacow@ubuntu:~/prog/golang/echo_test$ ab -n 10000 -c 100  http://localhost:1323/users/id/1
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 1000 requests
.....
Completed 10000 requests
Finished 10000 requests

Server Software:
Server Hostname:        localhost
Server Port:            1323

Document Path:          /users/id/1
Document Length:        11 bytes

Concurrency Level:      100
Time taken for tests:   9.156 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1280000 bytes
HTML transferred:       110000 bytes
Requests per second:    1092.21 [#/sec](mean)
Time per request:       91.557 [ms](mean)
Time per request:       0.916 [ms](mean, across all concurrent requests)
Transfer rate:          136.53 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   4.4      0      29
Processing:     9   90  24.9     88     213
Waiting:        9   89  25.1     87     213
Total:         25   91  24.3     89     213

Percentage of the requests served within a certain time (ms)
  50%     89
  66%    100
  75%    107
  80%    112
  90%    123
  95%    134
  98%    147
  99%    156
 100%    213 (longest request)

Requests per second: 1092.21 #/sec

Connectez Mongo à l'aide de pytho-flask et obtenez le résultat

Créez une application qui se connecte à mongo.

mongo_server.py



#!/usr/bin/env python
# -*- coding:utf-8 -*-

from flask import Flask
from flask_pymongo import PyMongo
app = Flask(__name__)
app.config['MONGO_HOST']='localhost'
app.config['MONGO_DBNAME'] = 'test'
mongo = PyMongo(app)

@app.route("/users/id/<int:id>")
def user_id(id):
    user= mongo.db.user.find_one({"id":id})
    msg="Hello id={} name={}".format(user["id"],user['name'])
    return msg

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == '__main__':
    app.run(host="0.0.0.0",debug=False)

Benchmark en utilisant python-flask

shibacow@ubuntu:~/prog/python/flask_test$ ab -n 10000 -c100 http://localhost:500
0/users/id/1
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 1000 requests
.....
Completed 10000 requests
Finished 10000 requests

Server Software:        Werkzeug/0.11.10
Server Hostname:        localhost
Server Port:            5000

Document Path:          /users/id/1
Document Length:        20 bytes

Concurrency Level:      100
Time taken for tests:   12.639 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      1760000 bytes
HTML transferred:       200000 bytes
Requests per second:    791.22 [#/sec](mean)
Time per request:       126.387 [ms](mean)
Time per request:       1.264 [ms](mean, across all concurrent requests)
Transfer rate:          135.99 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       8
Processing:     6  126  11.8    125     164
Waiting:        6  125  11.8    125     163
Total:         11  126  11.5    125     164

Percentage of the requests served within a certain time (ms)
  50%    125
  66%    129
  75%    131
  80%    132
  90%    138
  95%    143
  98%    149
  99%    153
 100%    164 (longest request)

Requests per second: 791.22 #/sec

Résumé

Nous avons comparé les vitesses de golang-echo et python-flask.

Comparaison Application simple Application complexe
golang-echo 10498 req/sec 1092 req/sec
python-flask 1220 req/sec 791 req/sec

Avec une application simple, les performances sont environ 10 fois différentes, mais lors de la connexion à mongo, il n'y a pas beaucoup de différence de vitesse. Il se connecte à mongo à chaque fois qu'il est demandé, donc cela peut être plus cher. Si echo et pymongo utilisent le pool de connexions, le résultat peut à nouveau changer. La raison pour laquelle j'ai comparé le golang et le python n'est pas parce que je veux réduire les performances de python, mais parce que je veux juste voir à quel point il y a de différence.

Résumé (note supplémentaire)

Comme mentionné dans le post-scriptum ci-dessous, si j'arrêtais de me connecter à mongo à chaque fois, que je le connectais une fois et que je le réutilisais, cela devenait beaucoup plus rapide. Cependant, comme la session conserve l'état, je ne sais pas à quoi cela ressemblera lors d'une mise à jour ou d'une validation, par exemple, une vérification sera donc nécessaire pour une utilisation dans un environnement de production autre que le benchmark.

Comparaison Application simple Application complexe
golang-echo 10498 req/sec 1092 req/sec
golang-echo(La version améliorée suivante) Aucun 6283.74 req/sec
python-flask 1220 req/sec 791 req/sec

Postscript golang-echo mongo Acquisition plus rapide des résultats en se connectant

amélioration de la connexion golang-echo mongo

Dans l'exemple ci-dessus, chaque requête a été connectée et déconnectée à plusieurs reprises de mongo. Arrêtez-le et connectez-vous et déconnectez-vous en dehors du GET. L'affichage sur la sortie standard étant source de lenteur, je l'ai arrêté.

mgo_server.go


package main

import (
        //Système serveur
        "net/http"
        "github.com/labstack/echo"
        "github.com/labstack/echo/engine/standard"

        //système mongo
        //"fmt" //La sortie standard est lente, alors arrêtez
        "gopkg.in/mgo.v2"
        "gopkg.in/mgo.v2/bson"

        //Moule
        "strconv"
        //"reflect"
)

//Classe d'utilisateurs
type User struct {
        Name  string `bson:"name"`
        Id int `bson:"id"`
}

func main() {
        e := echo.New()
        //J'ai tiré la base de données par id et l'ai mise en dehors du GET et j'ai arrêté de me connecter et de me déconnecter à chaque fois
        session, _ := mgo.Dial("mongodb://localhost")
        defer session.Close()
        db := session.DB("test")

        e.GET("/", func(c echo.Context) error {
                return c.String(http.StatusOK, "Hello, World!")
        })

        // :id, :Non trouvé si le nom ne contient pas de valeur
        e.GET("/users/id/:id", func(c echo.Context) error {

                //Besoin de convertir en nombre
                var id int
                id, _ = strconv.Atoi(c.Param("id"))


                //Obtenir l'utilisateur en spécifiant son identifiant
                var results []User
                //fmt.Println(id)
                db.C("user").Find(bson.M{"id": id}).All(&results)

                //fmt.Println("Results of one user: ", results)
                //fmt.Println(len(results))

                if len(results) == 0 {
                        return c.String(http.StatusOK, "No user")
                }else{
                        name := results[0].Name
                        return c.String(http.StatusOK, "Hello, " + name)
                }
        })

        e.POST("/user", func(c echo.Context) error {
                return c.String(http.StatusOK, "Hello, POST user")
        })

        //Port
        e.Run(standard.New(":1323"))
}

Benchmark amélioré

Après avoir apporté les améliorations ci-dessus, la vitesse a considérablement augmenté à ** 6292 ** req / sec.

shibacow@ubuntu:~$ ab -n 100000 -c 100 http://localhost:1323/users/id/1
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 10000 requests
....
Completed 100000 requests
Finished 100000 requests


Server Software:
Server Hostname:        localhost
Server Port:            1323

Document Path:          /users/id/1
Document Length:        11 bytes

Concurrency Level:      100
Time taken for tests:   15.914 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      12800000 bytes
HTML transferred:       1100000 bytes
Requests per second:    6283.74 [#/sec](mean)
Time per request:       15.914 [ms](mean)
Time per request:       0.159 [ms](mean, across all concurrent requests)
Transfer rate:          785.47 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    4   3.2      3      21
Processing:     0   12   5.0     12      44
Waiting:        0   10   4.9     10      44
Total:          0   16   5.2     15      45

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     17
  75%     19
  80%     20
  90%     22
  95%     25
  98%     29
  99%     32
 100%     45 (longest request)

Requests per second: 6283.74 #/sec

C'est beaucoup plus rapide.

Recommended Posts

J'ai comparé la vitesse de l'écho du framework web en langage go et du flask du framework web python
J'ai comparé la vitesse de Hash avec Topaz, Ruby et Python
J'ai remplacé le calcul numérique de Python par Rust et comparé la vitesse
J'ai comparé la vitesse des expressions régulières en Ruby, Python et Perl (version 2013)
J'ai comparé la vitesse de la référence du python dans la liste et la référence de l'inclusion du dictionnaire faite à partir de la liste dans.
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
J'ai mesuré la vitesse de la notation d'inclusion de liste, pendant et pendant avec python2.7.
Comparez la vitesse d'ajout et de carte Python
J'ai vérifié les versions de Blender et Python
J'ai comparé Java et Python!
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
Je veux connaître la nature de Python et pip
L'histoire de Python et l'histoire de NaN
J'ai comparé le temps de calcul de la moyenne mobile écrite en Python
[Python] J'ai expliqué en détail la théorie et la mise en œuvre de la régression logistique
[Python] J'ai expliqué en détail la théorie et la mise en œuvre de l'arbre de décision
J'ai essayé de créer un outil d'échafaudage pour le framework Web Python Bottle
J'ai comparé argparse standard python3 et python-fire
Essayez d'utiliser le framework d'application Web Flask
La structure des dossiers de Flask est résumée
Comparer la grammaire de base de Python et Go d'une manière facile à comprendre
Je ne connaissais pas les bases de Python
Développement et déploiement de l'API REST en Python à l'aide de Falcon Web Framework
J'ai essayé de vérifier et d'analyser l'accélération de Python par Cython
Le modèle de projet Python auquel je pense.
Je souhaite créer une application Web en utilisant React et Python flask
J'ai essayé le framework de test Python Tornado
J'ai fait go language pour api et la configuration minimum de react pour le front
[Python] J'ai créé un code de scraping web qui acquiert automatiquement le titre de l'actualité et l'URL de Nihon Keizai Shimbun.
[Python] J'ai expliqué en détail la théorie et l'implémentation de la machine à vecteurs de support (SVM).
J'ai comparé la moyenne mobile du type de filtre IIR avec les pandas et scipy
J'ai essayé le web scraping en utilisant python et sélénium
Résumé des différences entre PHP et Python
Python Web Framework Django vs Pyramid vs Flask Décembre 2015
La réponse de "1/2" est différente entre python2 et 3
Spécification de la plage des tableaux ruby et python
J'ai comparé "type de dictionnaire python" et "fonction excel"
Essayez d'utiliser le framework Web Python Tornado Partie 1
Installation de Python 3 et Flask [Résumé de la construction de l'environnement]
Essayez Progate Free Edition [Python I]
Lancer un serveur Web avec Python et Flask
J'ai vérifié la vitesse de traitement de la numpy unidimensionnelle
J'ai touché certaines des nouvelles fonctionnalités de Python 3.8 ①
Résumé relatif aux E / S de python et fortran
J'ai lu et implémenté les variantes de UKR
Essayez d'utiliser le framework Web Python Tornado Partie 2
Prise en compte des forces et faiblesses de Python
[Python3] Prenez une capture d'écran d'une page Web sur le serveur et recadrez-la davantage
Construisez un serveur API pour vérifier le fonctionnement de l'implémentation frontale avec python3 et Flask
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
L'histoire du portage du code de C vers Go (et vers la spécification du langage)
L'histoire de Python sans opérateurs d'incrémentation et de décrémentation.
Autour de l'installation du framework de gestion de projet Python Trac
Le processus d'installation d'Atom et de l'exécution de Python
Vitesse de lecture Python netCDF4 et imbrication d'instructions for
Python - Explication et résumé de l'utilisation des 24 meilleurs packages
J'ai comparé l'identité des images par moment Hu
Visualisez la gamme d'insertions internes et externes avec python