不服就来跑个分鸭
前几天跟朋友聊天的时候了解到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方法而已,不代表这么做是对的
- 最后,上面只是演示,只是演示,只是演示,重要的事情说三遍