前幾天跟朋友聊天的時候了解到python有個名為sanic的框架有着不錯的性能。
一時技癢,於是順便寫了一些沒有用的(這是真沒有用的)hello world程序來跑個分,看看這個sanic框架是否真的是性能上佳。
這里我們用到的性能測試工具(跑分工具)是wrk,安裝方便,使用簡單,效率爆表,擴展性強,是http服務benchmark(跑分)的不二選擇。
Flask
sanic看上去跟flask很像,當然了,只是看上去。沒有對比就沒有傷害,於是我便先開始對flask開始跑個分,以flask的得分作為基准,從而看看sanic對比flask在性能上是否有顯著提升(這就是基准測試,划重點,面試可能要考的)。
先寫個flask的hello world程序。
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def hello_world():
return jsonify(hello="world")
再跑起來。
env FLASK_APP=flask_test.py flask run
wrk去壓一下。我其實壓了幾次,逐步加壓,最后得到了一個最大的qps。
wrk -c 40 -t 10 http://localhost:5000/
Running 10s test @ http://localhost:5000/
10 threads and 40 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 56.77ms 153.66ms 1.16s 95.32%
Req/Sec 126.38 36.43 240.00 74.08%
11442 requests in 10.06s, 1.79MB read
Requests/sec: 1137.51
Transfer/sec: 182.18KB
flask的qps就是1137,我們把qps當作得分,最終得分1137。
sanic
sanic出場。首先是祖傳的hello world代碼。
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route("/")
async def test(request):
return json({"hello": "world"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=12306)
運行起來
python sanic_test.py
wrk開壓。
wrk -c 40 -t 10 http://localhost:12306/
Running 10s test @ http://localhost:12306/
10 threads and 40 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 7.95ms 8.40ms 115.06ms 95.11%
Req/Sec 585.85 193.25 1.05k 72.20%
58394 requests in 10.02s, 7.07MB read
Requests/sec: 5827.39
Transfer/sec: 722.73KB
wrk -c 50 -t 10 http://localhost:12306/
Running 10s test @ http://localhost:12306/
10 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 8.44ms 6.52ms 99.46ms 97.02%
Req/Sec 639.89 145.78 0.87k 71.70%
63752 requests in 10.02s, 7.72MB read
Requests/sec: 6363.14
Transfer/sec: 789.18KB
wrk -c 60 -t 10 http://localhost:12306/
Running 10s test @ http://localhost:12306/
10 threads and 60 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 9.11ms 3.82ms 61.37ms 91.40%
Req/Sec 668.59 113.54 0.86k 61.40%
66643 requests in 10.02s, 8.07MB read
Requests/sec: 6649.27
Transfer/sec: 824.67KB
wrk -c 70 -t 20 http://localhost:12306/
Running 10s test @ http://localhost:12306/
20 threads and 70 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 9.41ms 5.72ms 110.24ms 98.19%
Req/Sec 330.24 83.24 545.00 68.25%
65871 requests in 10.03s, 7.98MB read
Requests/sec: 6565.83
Transfer/sec: 814.32KB
逐步加壓運行了幾次,最終最大的qps是6649。
所以sanic的qps是flask的6倍左右。
go/gin
按道理來說sanic的性能比django的性能要好一些的,畢竟是輕量級的框架。所以sanic應該在python里算是一個性能不錯的框架了。那么問題就來了,同樣的功能,如果我用go去實現一遍,那么qps會有多少呢?
帶着這個疑問,我用gin這個框架實現了個相同功能的hello world。
順帶提一下,gin在go的各種框架里也算是性能非常好的了。
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"hello": "world",
})
})
r.Run()
}
跑起來,壓一下。
wrk -c 50 -t 20 http://localhost:8080
Running 10s test @ http://localhost:8080
20 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.61ms 4.34ms 90.14ms 98.15%
Req/Sec 1.73k 264.11 2.23k 84.09%
347366 requests in 10.10s, 46.71MB read
Requests/sec: 34383.89
Transfer/sec: 4.62MB
emm,qps是34383。大概是sanic的5倍,是flask的30倍。
總結
- sanic在python語言里是有不錯的性能優勢的,大家有興趣的同學可以深入的研究一下
- 把python跟go去做性能比較只是圖個樂子,沒有任何的引戰的目的
- 語言沒有好壞,每個語言都有自己的應用場景,脫離場景去比較語言優劣就是耍流氓
- 用hello world做benchmark其實也是耍流氓,因為根本沒有帶具體業務和應用場景,技術選型不能只依賴benchmark的結果,需要綜合考量
- 這里只是給大家演示一下基於基准值的benchmark方法而已,不代表這么做是對的
- 最后,上面只是演示,只是演示,只是演示,重要的事情說三遍