測試基本信息
主題:比較異步框架和同步框架在文件IO操作的性能差異
python版本:python 3.8
壓測工具:locust
web框架:同步:flask 異步:aiohttp、starlette
異步文件模塊:aiofiles、anyio.Path
請求併發量: 模擬10個用戶
服務器配置: Intel(R) i7-12700F
客戶端配置:Intel(R) i7-8700 3.20GHz
flask 同步框架
flask是python中輕量級web框架,特點是靈活、輕量級、擴展性高。同時flask是一個同步框架,文件操作內容是在請求中打開一個文件demo.txt,讀取文件內容,然後返回文件內容。
from flask import Flask, request
app = Flask(__name__)
@app.route('/file')
def file():
with open("demo.txt") as f:
text = f.read()
return text
if __name__ == '__main__':
app.run(port=8090, host="0.0.0.0")
壓測結果
併發量:453
aiohttp 異步框架
aiohttp 是一個基於 asyncio 的異步 HTTP 網絡模塊,它既提供了服務端,又提供了客戶端。由於python內置函數open不支持異步讀寫,所以選用異步文件讀寫速度最快的 aiofiles 模塊,打開同一個demo.txt文件。
from aiohttp import web
import aiofiles
routes = web.RouteTableDef()
@routes.get("/file")
async def file(request):
async with aiofiles.open("demo.txt") as fp:
text = await fp.read()
return web.Response(text=text)
if __name__ == '__main__':
app = web.Application()
app.add_routes(routes)
web.run_app(app)
壓測結果
併發量:1490
starlette 異步框架
starlette 是當下火熱的異步框架fastapi依賴的唯二模塊之一,主要用於異步請求的處理。anyio是starlette依賴的包,一個封裝asyncio的高級異步庫,自帶異步io操作。
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
from anyio import Path
async def file(request):
text = await Path('demo.txt').read_text()
return JSONResponse(text)
app = Starlette(debug=True, routes=[Route('/file', file),])
壓測結果
併發量:1538
對比
併發曲線圖對比:
參數對比:
框架 | 文件IO併發量 | 延遲 | 純框架無IO併發量 |
---|---|---|---|
flask | 453 | 21 ms | 463 |
aiohttp | 1490 | 6 ms | 1455 |
starlette | 1538 | 6 ms | 1539 |
總結
在文件讀寫方面,異步框架性能是同步框架的3倍左右。同一個框架相較於無IO併發時性能略有下降但並不是很多,這說明文件IO阻塞並嚴重。下一篇比較數據庫IO的併發性能。
準備連載一系列關於python異步編程的文章。包括同異步框架性能對比、異步事情驅動原理等。首發微信公衆號,歡迎關注第一時間閱讀。