Ich habe die ganze Zeit Python berührt und war nicht besonders unzufrieden damit, aber kürzlich habe ich Golang berührt. Python ist praktisch, um etwas zu erstellen, aber wenn Sie Geschwindigkeit brauchen, möchte ich ein Gefühl dafür bekommen, wie schnell es mit Golang sein kann, also Golangs typisches Web-Framework-Echo und Pythons leichtes Web-Framework Ich habe Flaschen verglichen, um festzustellen, wie stark sich die Geschwindigkeiten unterschieden.
Die auf VMware basierende Ubuntu 16.04-Festplatte ist eine normale Festplatte, keine SSD. i7,memory 6GB python2.7 golang 1.6
Versuchen Sie zunächst, eine einfache Web-App zu erstellen, um ein Gefühl dafür zu bekommen
Zunächst aus einer einfachen Web-App, die Golang verwendet
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"))
}
Wenn Sie die Echobibliothek mit Golang verwenden, können Sie diese problemlos als Webanwendung schreiben, die "Hello World" zurückgibt.
Lassen Sie uns die Geschwindigkeit mit der Apache-Bank sehen
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
Es scheint, dass ungefähr 10.000 Req / Sek. Ohne Abstimmung herauskommen werden.
Überprüfen Sie als nächstes den Kolben
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 gibt damit auch Hello World
zurück
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
Tun Sie nichts Besonderes und erhalten Sie ungefähr 1220 Req / Sek
Wenn es sich um eine einfache App handelt, unterscheidet sie sich vom eigentlichen Problem. Stellen Sie also eine Verbindung zu Mongo her, suchen Sie das Ergebnis und geben Sie es zurück usw. Ich habe auf diese [Website] verwiesen (http://peroon.hatenablog.com/entry/2016/08/04/181956).
mgo_server.go
package main
import (
//Serversystem
"net/http"
"github.com/labstack/echo"
"github.com/labstack/echo/engine/standard"
//Mongo-System
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
//Schimmel
"strconv"
//"reflect"
)
//Benutzerklasse
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, :Nicht gefunden, wenn der Name keinen Wert enthält
e.GET("/users/id/:id", func(c echo.Context) error {
//Müssen in Zahl konvertieren
var id int
id, _ = strconv.Atoi(c.Param("id"))
//Subtrahiere DB von id
session, _ := mgo.Dial("mongodb://localhost")
defer session.Close()
db := session.DB("test")
//Holen Sie sich den Benutzer durch Angabe der ID
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")
})
//Hafen
e.Run(standard.New(":1323"))
}
Ein Benchmark dessen, was sich mit Mongodb verbindet und Ergebnisse liefert
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
Erstellen Sie eine App, die sich mit Mongo verbindet.
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
Wir haben die Geschwindigkeiten von Golang-Echo und Python-Kolben verglichen.
Vergleich | Einfache App | Komplexe App |
---|---|---|
golang-echo | 10498 req/sec | 1092 req/sec |
python-flask | 1220 req/sec | 791 req/sec |
Mit einer einfachen App ist die Leistung ungefähr zehnmal anders, aber wenn Sie eine Verbindung zu Mongo herstellen, gibt es keinen großen Unterschied in der Geschwindigkeit. Es verbindet sich jedes Mal mit Mongo, wenn es angefordert wird, daher kann es teurer sein. Wenn sowohl Echo als auch Pymongo den Verbindungspool verwenden, kann sich das Ergebnis erneut ändern. Der Grund, warum ich Golang und Python verglichen habe, ist nicht, dass ich die Leistung von Python reduzieren möchte, sondern nur, wie viel Unterschied es gibt.
Wie im folgenden Postskriptum erwähnt, wurde es viel schneller, wenn ich jedes Mal die Verbindung zu Mongo abbrach und es einmal verband und wiederverwendete. Da die Sitzung jedoch den Status beibehält, weiß ich nicht, wie sie beispielsweise beim Aktualisieren oder Festschreiben aussehen wird. Daher ist eine Überprüfung für die Verwendung in einer anderen Produktionsumgebung als dem Benchmark erforderlich.
Vergleich | Einfache App | Komplexe App |
---|---|---|
golang-echo | 10498 req/sec | 1092 req/sec |
golang-echo(Die folgende verbesserte Version) | Keiner | 6283.74 req/sec |
python-flask | 1220 req/sec | 791 req/sec |
Im obigen Beispiel wurde jede Anforderung wiederholt mit Mongo verbunden und von diesem getrennt. Stoppen Sie es und verbinden und trennen Sie es außerhalb des GET. Da die Anzeige auf der Standardausgabe eine Quelle der Langsamkeit ist, habe ich sie gestoppt.
mgo_server.go
package main
import (
//Serversystem
"net/http"
"github.com/labstack/echo"
"github.com/labstack/echo/engine/standard"
//Mongo-System
//"fmt" //Die Standardausgabe ist langsam, also hören Sie auf
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
//Schimmel
"strconv"
//"reflect"
)
//Benutzerklasse
type User struct {
Name string `bson:"name"`
Id int `bson:"id"`
}
func main() {
e := echo.New()
//Ich habe die Datenbank anhand der ID gezogen und außerhalb des GET abgelegt und jedes Mal aufgehört, eine Verbindung herzustellen und zu trennen
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, :Nicht gefunden, wenn der Name keinen Wert enthält
e.GET("/users/id/:id", func(c echo.Context) error {
//Müssen in Zahl konvertieren
var id int
id, _ = strconv.Atoi(c.Param("id"))
//Holen Sie sich den Benutzer durch Angabe der ID
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")
})
//Hafen
e.Run(standard.New(":1323"))
}
Nach den obigen Verbesserungen hat sich die Geschwindigkeit erheblich auf ** 6292 ** req / sec erhöht.
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
Es ist viel schneller.