Python3 中在同步代码的框架中使用 asyncio 异步(async/await),是否能提升性能?

2021-03-03 17:45:27 +08:00
 xutaoding

假如用 flask 或者 django(不使用异步部署)这样的框架,在视图函数中使用 asyncio,对程序的性能是有提升? 如果没有提升或提升不大或结果不可预测,那么使用 asyncio 这样的异步库对程序性能提升的前提限制都有哪些?

2821 次点击
所在节点    Python
21 条回复
qW7bo2FbzbC0
2021-03-03 17:58:10 +08:00
推荐使用异步含量更高的语言
xcstream
2021-03-03 18:02:06 +08:00
不能
iConnect
2021-03-03 18:03:27 +08:00
喜欢 asyncio 直接用 fastapi,不要用 django 、flask 这些同步框架,框架作者都没打算上 asyncio,自己 hack 有很多问题。
acmore
2021-03-03 18:06:55 +08:00
不可预测,CPU 密集的项目用异步用处不大,比如你的项目是用来做大数质因分解的。
异步主要用于网络和高 I/O 的项目,本质就是把 CPU 傻等的那段时间拿过来利用。
你可以模拟下真实的网络环境跑个 benchmark 看看。
clino
2021-03-03 18:10:19 +08:00
性能是不能提升的,只能提升并发数量

如果并发能用到多核,比如开多个子进程进行计算,倒是可以算是提升了性能,但是在 web 框架里用应该没有这种情况发生
superrichman
2021-03-03 18:17:06 +08:00
一处异步,处处异步
从 0 开始吧
tomczhen
2021-03-03 18:19:10 +08:00
带有偏见看事物才是最有问题的,比如说 Django 都已经主推 asgi 了,到这里就变成“根本没打算上 asyncio”,再说 Python 异步生态又不是只有 asyncio 啊。

回到异步对 Python 性能提升的话题,我觉得可以看看 https://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/
iConnect
2021-03-03 18:28:48 +08:00
@tomczhen 哪里看到 django 社区 主推 asgi 啦?异步 ORM 都准备好了?
iConnect
2021-03-03 18:36:50 +08:00
@tomczhen 正是因为 py 异步方案多,这几个主流的同步框架才不急着跟进吧
Vegetable
2021-03-03 18:37:59 +08:00
应该说可以在某些情况下提升效率,通过使用局部异步的方式。不过这么做和直接用多线程没啥区别。
比如这段代码 https://gist.github.com/luliangce/9f9ce635a62f4b60e3109177630b0a30

用异步的确比同步快,但其实没什么意义。
LeeReamond
2021-03-03 18:46:34 +08:00
David beazly 在一开始讲异步的时候就很明确的总结,异步来自 Python 的另外一个宇宙( Universe ),其功能是通过维护一个事件循环,以复用的方式加速 IO 。和同步宇宙最大的区别在于异步宇宙中 func()并不像同步宇宙一样代表执行某任务,而是仅代表定义任务,执行在稍后。你想跟基于线程模型的同步 IO 混用,比如在 flask 框架里,那你要如何安排你的事件循环呢?
renmu123
2021-03-03 18:50:34 +08:00
Python 的异步生态还不够成熟
love
2021-03-03 19:26:31 +08:00
异步库不是用来提升性能的吧,不觉得会比传统的同步多进程性能好
chroming
2021-03-03 21:11:51 +08:00
当初开始使用 fastapi 时自己本机测了下有一点业务代码的相同接口,fastapi+uvicorn 差不多比 flask+gunicorn 快一倍
iConnect
2021-03-03 21:24:25 +08:00
@chroming 有没有印象,两种测试方案下,当时 CPU 和内存的占用分别达到多少?还是都跑满测试的?
todd7zhang
2021-03-04 09:15:28 +08:00
@chroming 难道不是并发多一倍而已嘛?之前业务逻辑响应要 30ms,改成异步就能 15ms 了?
abersheeran
2021-03-04 09:36:40 +08:00
@chroming 好家伙,你拿一个性能最拉跨 WSGI 框架跟一个有 C 库加持的 ASGI 框架比性能。这是让巴基斯坦打 China,铁定输啊。

要比性能,你可以换一个,比如 bottle+gunicorn+meinheld 与 starlette+uvicorn 比。一个是 WSGI 高性能的代表,一个是 ASGI 高性能的代表。
abersheeran
2021-03-04 09:41:04 +08:00
提升的前提有这么几个:属于 IO 密集型任务( CPU 密集你只能上 C/Rust 拓展),代码里没有任何同步 IO 代码(无栈协程有传染性),原有项目使用多线程模型导致了大量的线程切换损耗(如果你用 gevent 之类的去改造过了,asyncio 不会比 gevent 更快)。

三个条件,任何一个不满足,都得不到显著的提升。这三个是必要条件,不一定是充分条件。
xpresslink
2021-03-04 10:12:04 +08:00
以海底捞火锅举例,性能是由台数决定的,门口等座椅子数量只能决定能拖住多少客人暂时不走。使用异步只是提高了等座椅子数量,最终决定性能的还是要靠 CPU 、磁盘、网络 IO 的处理能力。
wangyzj
2021-03-04 11:35:26 +08:00
io 密集型可以提高并发,还是要快一点

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/758128

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX