I compared the speed of go language web framework echo and python web framework flask

Compare the execution speed of golang-echo and python-flask

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.

testing environment

The ubuntu 16.04 hdd built on vmware is a normal one, not an ssd. i7,memory 6GB python2.7 golang 1.6

A web app that returns a simple string

First, let's make a simple web application to get a feel for it.

A simple app using golang-echo

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 measure the speed of golang-echo

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.

A simple app using python-flask

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

python-flask 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

Do nothing in particular and get about 1220 req / sec

A web app that connects to Mongodb, searches and returns results

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.

web app that connects to mongo using golang-echo

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

golang-echo mongo connection benchmark

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

Connect mongo using pytho-flask and get the result

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)

Benchmark using 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

Summary

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.

Summary (additional note)

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

Postscript golang-echo mongo Faster to connect and get results

golang-echo mongo connection improvement

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

Improved benchmark

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

I compared the speed of go language web framework echo and python web framework flask
I compared the speed of Hash with Topaz, Ruby and Python
I replaced the numerical calculation of Python with Rust and compared the speed
I compared the speed of regular expressions in Ruby, Python, and Perl (2013 version)
I compared the speed of the reference of the python in list and the reference of the dictionary comprehension made from the in list.
[Introduction to Python] I compared the naming conventions of C # and Python.
I measured the speed of list comprehension, for and while with python2.7.
Compare the speed of Python append and map
I checked out the versions of Blender and Python
I compared Java and Python!
I tried to compare the processing speed with dplyr of R and pandas of Python
I want to know the features of Python and pip
The story of Python and the story of NaN
I compared the calculation time of the moving average written in Python
[Python] I thoroughly explained the theory and implementation of logistic regression
[Python] I thoroughly explained the theory and implementation of decision trees
I made a scaffolding tool for the Python web framework Bottle
I compared python3 standard argparse and python-fire
Try using the web application framework Flask
I summarized the folder structure of Flask
Comparing the basic grammar of Python and Go in an easy-to-understand manner
I didn't know the basics of Python
Development and deployment of REST API in Python using Falcon Web Framework
I tried to verify and analyze the acceleration of Python by Cython
The Python project template I think of.
I want to make a web application using React and Python flask
I tried the Python Tornado Testing Framework
I made go language for api and minimum configuration of react for front
[Python] I made a web scraping code that automatically acquires the news title and URL of Nikkei Inc.
[ES Lab] I tried to develop a WEB application with Python and Flask ②
[Python] I thoroughly explained the theory and implementation of support vector machine (SVM)
I compared the moving average of IIR filter type with pandas and scipy
I tried web scraping using python and selenium
Summary of the differences between PHP and Python
Python web framework Django vs Pyramid vs Flask December 2015
The answer of "1/2" is different between python2 and 3
Specifying the range of ruby and python arrays
I compared "python dictionary type" and "excel function"
Try using the Python web framework Tornado Part 1
Installation of Python3 and Flask [Environment construction summary]
Try the free version of Progate [Python I]
Launch a web server with Python and Flask
I checked the processing speed of numpy one-dimensionalization
I touched some of the new features of Python 3.8 ①
I wrote the hexagonal architecture in go language
I / O related summary of python and fortran
I read and implemented the Variants of UKR
Try using the Python web framework Tornado Part 2
About the * (asterisk) argument of python (and itertools.starmap)
A discussion of the strengths and weaknesses of Python
[Python3] Take a screenshot of a web page on the server and crop it further
Build API server for checking the operation of front implementation with python3 and Flask
I tried to automate the article update of Livedoor blog with Python and selenium.
The story of porting code from C to Go and getting hooked (and to the language spec)
The story of Python without increment and decrement operators.
Around the installation of the Python project management framework Trac
The process of installing Atom and getting Python running
Python netCDF4 read speed and nesting of for statements
Python --Explanation and usage summary of the top 24 packages
I compared the identity of the images by Hu moment
Visualize the range of interpolation and extrapolation with python