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.
Le disque dur ubuntu 16.04 construit sur vmware est normal, pas ssd. i7,memory 6GB python2.7 golang 1.6
Essayez d'abord de créer une application Web simple pour vous faire une idée
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
.
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.
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
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
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.
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"))
}
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
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)
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
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.
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 |
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"))
}
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.