I've been touching python all the time and haven't been particularly dissatisfied, but recently I've been touching golang. Python is convenient for making something, but I want to get a feel for how fast it can be with golang when speed is needed, so golang's typical web framework echo and python's lightweight web framework I compared flasks to see how much the speeds differed.
The ubuntu 16.04 hdd built on vmware is a normal one, not an ssd. i7,memory 6GB python2.7 golang 1.6
First, let's make a simple web application to get a feel for it.
First of all, from a simple web application using 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"))
}
If you use the echo library with golang, you can easily write this as a web application that returns Hello World
.
Let's see the speed using apache bench
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
It seems that about 10,000 req / sec will be output without tuning.
Next, check the flask
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 also returns Hello World
with this
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
Do nothing in particular and get about 1220 req / sec
If it is a simple application, it will be different from the actual problem, so connect to mongo, search and return the result, etc., and put something a little more than reality. I referred to this site.
mgo_server.go
package main
import (
//Server system
"net/http"
"github.com/labstack/echo"
"github.com/labstack/echo/engine/standard"
//mongo system
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
//Mold
"strconv"
//"reflect"
)
//User class
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, :Not Found if name does not contain a value
e.GET("/users/id/:id", func(c echo.Context) error {
//Need to convert to number
var id int
id, _ = strconv.Atoi(c.Param("id"))
//Subtract DB by id
session, _ := mgo.Dial("mongodb://localhost")
defer session.Close()
db := session.DB("test")
//Get user by specifying 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")
})
//port
e.Run(standard.New(":1323"))
}
Benchmark of what connects to mongodb and returns results
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
Create an app that connects with 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
I compared the speed of golang-echo and python-flask.
Comparison | Simple app | Complex app |
---|---|---|
golang-echo | 10498 req/sec | 1092 req/sec |
python-flask | 1220 req/sec | 791 req/sec |
With a simple app, the performance is about 10 times different, but when connecting to mongo, there is not much difference in speed. Since it connects to mongo every time it requests, it may be more expensive. If both echo and pymongo use connection pools, the results may change again. The reason I compared golang and python is not because I want to reduce the performance of python, but because I just want to experience how much difference there is.
As mentioned in the postscript below, if I stopped connecting to mongo every time and connected it once and reused it, it became much faster. However, since the session keeps its state, I don't know what it will be like when updating or committing, for example, so it will need to be verified for use in a production environment other than benchmarking.
Comparison | Simple app | Complex app |
---|---|---|
golang-echo | 10498 req/sec | 1092 req/sec |
golang-echo(The following improved version) | None | 6283.74 req/sec |
python-flask | 1220 req/sec | 791 req/sec |
In the above example, each request was repeatedly connected and disconnected from mongo. Stop it and connect and disconnect outside the GET. Since the display on the standard output is a source of slowness, I stopped it.
mgo_server.go
package main
import (
//Server system
"net/http"
"github.com/labstack/echo"
"github.com/labstack/echo/engine/standard"
//mongo system
//"fmt" //Standard output is slow, so stop
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
//Mold
"strconv"
//"reflect"
)
//User class
type User struct {
Name string `bson:"name"`
Id int `bson:"id"`
}
func main() {
e := echo.New()
//I pulled the DB by id and put it outside the GET and stopped connecting and disconnecting every time
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, :Not Found if name does not contain a value
e.GET("/users/id/:id", func(c echo.Context) error {
//Need to convert to number
var id int
id, _ = strconv.Atoi(c.Param("id"))
//Get user by specifying 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")
})
//port
e.Run(standard.New(":1323"))
}
After making the above improvements, the speed has increased considerably to ** 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
It's much faster.
Recommended Posts