无脑吹FastAPI性能碾压Flask(关于网上不合适的性能对比以及让我糊涂的自测结果)
不止一次的听过,有个FastAPI框架,性能碾压Flask,直追Golang,不过一直没有测试过,今天闲着没事测试一下看看结果。不知道是哪里出了问题,结果大跌眼镜。
测试之前
为了偷懒,自然想先从网上找找前人的测试代码以作为参照。百度前几名关于FastAPI和Flask性能测试又带了代码的有下面几个:
- FastAPI、Flask、Golang性能测试
- Flask、Django、Tornado、FastAPI 之 Python Web 并发测试
- flask,tornado,fastapi 压测比较(web框架)
我觉得这样应该是有问题的,且不说本来二者都不是同一层次的框架(FastAPI是基于Starlette的,这才是应该和Flask对比的框架),就算对比,也应该用差不多的启动方式吧?
unicorn是个第三方ASGI服务器,Flask应该用一个第三方WSGI服务器来启动才正常吧?感觉用它自带的WSGI服务器比可能不太公平。
我本来想用gunicorn来启动Flask进行对比的,结果发现不兼容Windows,所以换了个waitress,差不多的WSGI框架。
开始测试
- 环境:
Win10 Python3.8.9 各依赖库全是最新版
./siege.exe -b -t10s http://127.0.0.1:5000/
测试代码和之前搜到的一样,用二者官网的例子,输出HelloWorld,略作修改,把启动代码写进文件内,就不用使用命令行启动了。
- Flask
from flask import Flask from waitress import serveapp = Flask(__name__)@app.route('/') def index(): return {'message': 'hello world'}if __name__ == '__main__': app.run(host='0.0.0.0') # serve(app, host='0.0.0.0', port=5000)
- FastAPI
from fastapi import FastAPI import uvicornapp = FastAPI()@app.get("/") async def read_root(): return {"Hello": "World"}if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=5000)
除此之外,还测试了FastAPI使用异步的结果(就加了个async,实际应该什么没用的,文档中明确说了,只有函数内部使用了异步函数且需要同步返回时,也就是需要在内部用await时,才需要定义async)。
结果如下:
- flask
Transactions:4579 hits Availability:100.00 % Elapsed time:9.15 secs Data transferred:0.11 MB Response time:0.03 secs Transaction rate:500.66 trans/sec Throughput:0.01 MB/sec Concurrency:14.93 Successful transactions:4579 Failed transactions:0 Longest transaction:0.10 Shortest transaction:0.02
- flask + waitress
Transactions:12598 hits Availability:100.00 % Elapsed time:10.02 secs Data transferred:0.31 MB Response time:0.01 secs Transaction rate:1257.03 trans/sec Throughput:0.03 MB/sec Concurrency:14.89 Successful transactions:12598 Failed transactions:0 Longest transaction:0.03 Shortest transaction:0.00
- fastapi + uvicorn
Transactions:5278 hits Availability:100.00 % \Elapsed time:9.05 secs Data transferred:0.09 MB Response time:0.03 secs Transaction rate:583.20 trans/sec Throughput:0.01 MB/sec Concurrency:14.93 Successful transactions:5278 Failed transactions:0 Longest transaction:0.11 Shortest transaction:0.01
- fastapi + uvicorn + async
Transactions:5876 hits Availability:100.00 % \Elapsed time:9.31 secs Data transferred:0.10 MB Response time:0.02 secs Transaction rate:631.22 trans/sec Throughput:0.01 MB/sec Concurrency:14.84 Successful transactions:5876 Failed transactions:0 Longest transaction:0.12 Shortest transaction:0.00
- Flask直接启动结果比FastAPI启动结果略差一些(500:583/631)
- FastAPI用不用异步async差别不大(583:631)
- Flask用waitress WSGI服务器启动结果比不用快了2.5倍(1257:500),同样也比FastAPI快2倍左右
Flask直接启动比FastAPI慢一点是在意料之中的,但是使用waitress WSGI服务器启动后快这么多肯定也是不正常的。
于是我去查看了二者启动的源码,发现waitress默认4线程,unicorn默认1线程。。。
只好把Flask修改为1线程重新测试
serve(app, host='0.0.0.0', port=5000, threads=1)
结果如下:
Transactions:7492 hits
Availability:100.00 %
Elapsed time:9.07 secs
Data transferred:0.19 MB
Response time:0.02 secs
Transaction rate:825.84 trans/sec
Throughput:0.02 MB/sec
Concurrency:14.89
Successful transactions:7492
Failed transactions:0
Longest transaction:0.07
Shortest transaction:0.01
把unicorn修改为4线程重新测试
uvicorn.run("test-fastapi:app", host="0.0.0.0", port=5000, workers=4)# 需要同目录下新建`pyproject.toml`文件,内容为:
[tool.poetry.scripts]
start = "test-fastapi:start"
结果如下:
Transactions:7782 hits
Availability:100.00 %
Elapsed time:9.24 secs
Data transferred:0.13 MB
Response time:0.02 secs
Transaction rate:842.39 trans/sec
Throughput:0.01 MB/sec
Concurrency:14.92
Successful transactions:7782
Failed transactions:0
Longest transaction:0.15
Shortest transaction:0.00
可以看出:
- Flask用waitress WSGI服务器单线程启动结果比不用快了65%(825:500),同样也比FastAPI快很多(825:583/631)
- unicorn用4线程启动提升很小(842:583/631),和waitress单线程差不多
理论上说不通啊,unicorn开4线程后结果只有1倍多,waitress开4线程快了2倍多,代表着4线程都没完全利用到,而且unicorn单线程足处理能力更强吧,不知道为什么结果差这么多。
可能是测试工具的原因吧,毕竟别人都用的AB,还都指定并发数,我用的siege,没限制并发。
而且unicorn文档还提到可以使用Gunicorn管理进程,可能性能还会提升,碍于设备原因我就不测试了。
写在最后 做这个测试的本意是反驳前文提到的原因,只是想说,对比测试时应该使用第三方WSGI服务器启动Flask。
另外,性能测试肯定要加上基本功能啊,起码要有数据接收、处理、返回整个流程吧,只测试HelloWorld没什么代表性。
现在最终测试结果我也不敢确定了,只能保证测试数据和代码绝对真实,看到本文的朋友最好自己测试一遍,顺便告诉我为什么会出现这个结果。
还是多说一句,网上太多无脑吹FastAPI的人了,不否认它的优点,比如支持异步、ws、自动生成文档、强调声明变量类型等,但也没必要死踩Flask上位。
【无脑吹FastAPI性能碾压Flask(关于网上不合适的性能对比以及让我糊涂的自测结果)】连写文带测试花了几个小时,闲的。
推荐阅读
- 修身当如水
- 凤凰台上忆吹箫·忆巷
- 错笔
- 还记风吹水上鳞
- 我的心是被你吹奏的埙
- 时光|时光 邂逅
- 风吹一季——写在大学的尾巴上
- thanks|thanks leslie
- 阅读打卡(《吹牛大王历险记》)
- 十分搞笑的沙雕文案