V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
xutaoding
V2EX  ›  Python

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

  •  
  •   xutaoding · 2021-03-03 17:45:27 +08:00 · 2814 次点击
    这是一个创建于 1387 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

    三个条件,任何一个不满足,都得不到显著的提升。这三个是必要条件,不一定是充分条件。
    xpresslink
        19
    xpresslink  
       2021-03-04 10:12:04 +08:00
    以海底捞火锅举例,性能是由台数决定的,门口等座椅子数量只能决定能拖住多少客人暂时不走。使用异步只是提高了等座椅子数量,最终决定性能的还是要靠 CPU 、磁盘、网络 IO 的处理能力。
    wangyzj
        20
    wangyzj  
       2021-03-04 11:35:26 +08:00
    io 密集型可以提高并发,还是要快一点
    mlbjay
        21
    mlbjay  
       2023-07-21 15:00:38 +08:00
    python 的 asyncio 是纯用户态线程,同步 io 会阻塞整个线程及其中的所有协程。
    Golang 的 MPG 就解决的这个问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4371 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 10:09 · PVG 18:09 · LAX 02:09 · JFK 05:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.