Ich verglich die Geschwindigkeit von Go Language Web Framework Echo und Python Web Framework Flask

Vergleichen Sie die Ausführungsgeschwindigkeiten von Golang-Echo und Python-Kolben

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.

Testumgebung

Die auf VMware basierende Ubuntu 16.04-Festplatte ist eine normale Festplatte, keine SSD. i7,memory 6GB python2.7 golang 1.6

Eine Web-App, die eine einfache Zeichenfolge zurückgibt

Versuchen Sie zunächst, eine einfache Web-App zu erstellen, um ein Gefühl dafür zu bekommen

Eine einfache App mit Golang-Echo

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.

Versuchen Sie, die Geschwindigkeit des Golang-Echos zu messen

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.

Einfache App mit Python-Flasche

Ü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

Python-Kolben-Benchmark

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

Eine Web-App, die eine Verbindung zu Mongodb herstellt, Ergebnisse sucht und zurückgibt

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

Web-App, die über Golang-Echo eine Verbindung zu Mongo herstellt

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"))
}

Golang-Echo-Mongo-Verbindungsbenchmark

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

Verbinden Sie Mongo mit Python-Kolben und erhalten Sie das Ergebnis

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)

Benchmark mit Python-Kolben

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

Zusammenfassung

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.

Zusammenfassung (zusätzlicher Hinweis)

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

Postscript golang-echo mongo Schnellere Erfassung von Ergebnissen durch Verbinden

Verbesserung der Golang-Echo-Mongo-Verbindung

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"))
}

Verbesserter Benchmark

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.

Recommended Posts

Ich verglich die Geschwindigkeit von Go Language Web Framework Echo und Python Web Framework Flask
Ich habe die Geschwindigkeit von Hash mit Topaz, Ruby und Python verglichen
Ich habe die numerische Berechnung von Python durch Rust ersetzt und die Geschwindigkeit verglichen
Ich habe die Geschwindigkeit regulärer Ausdrücke in Ruby, Python und Perl (Version 2013) verglichen.
Ich habe die Geschwindigkeit der Referenz des Pythons in der Liste und die Referenz der Wörterbucheinbeziehung aus der In-Liste verglichen.
[Einführung in Python] Ich habe die Namenskonventionen von C # und Python verglichen.
Ich habe die Geschwindigkeit der Listeneinschlussnotation für und während mit Python2.7 gemessen.
Vergleichen Sie die Geschwindigkeit von Python Append und Map
Ich habe mir die Versionen von Blender und Python angesehen
Ich habe Java und Python verglichen!
Ich habe versucht, die Verarbeitungsgeschwindigkeit mit dplyr von R und pandas von Python zu vergleichen
Ich möchte die Natur von Python und Pip kennenlernen
Die Geschichte von Python und die Geschichte von NaN
Ich habe die Berechnungszeit des in Python geschriebenen gleitenden Durchschnitts verglichen
[Python] Ich habe die Theorie und Implementierung der logistischen Regression gründlich erklärt
[Python] Ich habe die Theorie und Implementierung des Entscheidungsbaums gründlich erklärt
Ich habe versucht, ein Gerüstwerkzeug für Python Web Framework Bottle zu erstellen
Ich habe Python3 Standard Argparse und Python-Fire verglichen
Versuchen Sie es mit dem Webanwendungsframework Flask
Die Ordnerstruktur von Flask ist zusammengefasst
Ein leicht verständlicher Vergleich der grundlegenden Grammatik von Python und Go
Ich kannte die Grundlagen von Python nicht
Entwicklung und Bereitstellung der REST-API in Python mit Falcon Web Framework
Ich habe versucht, die Beschleunigung von Python durch Cython zu verifizieren und zu analysieren
Die Python-Projektvorlage, an die ich denke.
Ich möchte eine Webanwendung mit React und Python Flask erstellen
Ich habe das Python Tornado Testing Framework ausprobiert
Ich habe go Sprache für API und die minimale Konfiguration der Reaktion für die Front gemacht
[Python] Ich habe einen Web-Scraping-Code erstellt, der automatisch den Nachrichtentitel und die URL von Nihon Keizai Shimbun erfasst.
[Python] Ich habe die Theorie und Implementierung der Support Vector Machine (SVM) ausführlich erklärt.
Ich habe den gleitenden Durchschnitt des IIR-Filtertyps mit Pandas und Scipy verglichen
Ich habe versucht, Web-Scraping mit Python und Selen
Zusammenfassung der Unterschiede zwischen PHP und Python
Python Web Framework Django gegen Pyramide gegen Flasche Dezember 2015
Die Antwort von "1/2" unterscheidet sich zwischen Python2 und 3
Angeben des Bereichs von Ruby- und Python-Arrays
Ich habe "Python Dictionary Type" und "Excel Function" verglichen.
Versuchen Sie es mit dem Python-Webframework Tornado Part 1
Installation von Python 3 und Flask [Zusammenfassung der Umgebungskonstruktion]
Probieren Sie Progate Free Edition [Python I]
Starten Sie einen Webserver mit Python und Flask
Ich habe die Verarbeitungsgeschwindigkeit der numpy eindimensionalisierung überprüft
Ich habe einige der neuen Funktionen von Python 3.8 touched angesprochen
E / A-bezogene Zusammenfassung von Python und Fortan
Ich habe die Varianten von UKR gelesen und implementiert
Versuchen Sie es mit dem Python-Webframework Tornado Part 2
Berücksichtigung der Stärken und Schwächen von Python
[Python3] Machen Sie einen Screenshot einer Webseite auf dem Server und schneiden Sie sie weiter zu
Erstellen Sie einen API-Server, um den Betrieb der Front-Implementierung mit Python3 und Flask zu überprüfen
Ich habe versucht, das Artikel-Update des Livedoor-Blogs mit Python und Selen zu automatisieren.
Die Geschichte der Portierung von Code von C nach Go (und zur Sprachspezifikation)
Die Geschichte von Python ohne Inkrement- und Dekrementoperatoren.
Rund um die Installation des Python-Projektmanagement-Frameworks Trac
Der Prozess der Installation von Atom und der Ausführung von Python
Python netCDF4 Lesegeschwindigkeit und Verschachtelung von for-Anweisungen
Python - Erläuterung und Zusammenfassung der Verwendung der 24 wichtigsten Pakete
Ich verglich die Identität der Bilder nach Hu Moment
Visualisieren Sie den Bereich der internen und externen Einfügungen mit Python