写点什么

你必须要会 uvloop!让 Python asyncio 异步编程性能直逼 Go 协程性能

作者:HullQin
  • 2022 年 8 月 29 日
    广东
  • 本文字数:1579 字

    阅读完需:约 5 分钟

我是 HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者 HullQin 授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还独立开发了《合成大西瓜重制版》。还开发了《Dice Crush》参加 Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。

背景

最近我在思考后端优化的事情,了解到了 uvloop,它是 python 原生 asyncio 事件循环的替代品。

先介绍下 asyncio

Python 从 3.4 开始,引入了asyncio库,参考PEP-3156。Python 从 3.5 开始,引入了asyncawait语法,参考PEP-0492


Python 中的用法其实跟 javascript 中的asyncawait相似,毕竟脚本语言的规范,基本都是抄来抄去,都愿意把隔壁语言的优秀语法吸纳进来。这对开发者也很爽,更容易学另一门语言了。


Python3.4 和 3.5 算是推动了一场革命,自此,Python 异步编程越来越火(基于协程)。


也许你不懂协程,我简单介绍下:


以前我们用 Python 写爬虫,可能会用requests这个库,requests.get(url)发请求,等到有了结果,代码再继续进行下去。它是顺序的同步的执行。当请求发生时,你只能傻傻的等,不能让代码去做另一件事。除非你新开一个线程去做另一件事。

但是现在,我们有了异步编程。基于内置的事件循环,我们可以达到这样的效果:遇到 I/O 操作(例如 Http 请求)时,我们先暂停这段代码(这个任务)的执行,再去看看有没有其它任务可以执行,如果有其它任务可执行,就执行其它任务。如果所有任务都无法执行,就等着,直到有 1 个任务可执行了,就执行它,直到它运行完毕或者遇到 I/O 操作,再暂停它,执行其它任务。


注意,Python 中的异步编程,是基于事件循环的。今天,我们要聊的就是事件循环。

关于 uvloop

uvloopPython 原生事件循环的替代品。提高了性能。

为什么提高了性能

(说法来源于 uvloop 官方博客)


  1. uvloop 是基于 Cython 写的,执行效率更高。

  2. uvloop 底层基于libuv,而libuv是高性能、跨平台的异步 IO 库,nodejs 的事件循环也是基于libuv的。

Benchmarks

这不是我做的,我只是转发一下 uvloop 官方测试结果。


分为两种测试:TCP 协议和 HTTP 协议。

TCP

这是用简单的 echo 服务做的测试,不能代表所有生产环境的情况。


分别用 1KiB 数据包、10KiB、100KiB 做了测试。



可以看到 uvloop 确实牛逼,性能直逼 Go。

HTTP


解释下:官方人员本来想用aiohttp这个 Python 中最常用的异步 http 服务库测试的。但是它的 http 解析器效率太低了,已然成为整个系统的瓶颈,所以他们手动实现了http-parser(起初是为 Nginx 设计的,所以效率非常高)的 Python 版本,称之为httptools


可以看到,asyncio 原生事件循环和 uvloop,对 aiohttp 没有性能提升!(看完后,我想:以后不敢用 aiohttp 了)


而把 http 解析器这个瓶颈解决掉后,asyncio 原生事件循环和 uvloop 性能都明显提升,但 uvloop 明显更牛逼,在 10KiB 和 100KiB 场景下,性能超越了 Go。

uvloop 有缺点吗

有,不支持 Windows。

怎么使用 uvloop

安装

pip install uvloop
复制代码

引入

import asyncioimport uvloopasyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
复制代码


其它 async 代码不变,你就享受到了更快的事件循环!

感受

如果一味追求性能,还是直接用 Go 吧。


但是 uvloop 确实给 Python 开发者提供了更强的性能,对于 Python 开发者很爽。但是也要注意,有没有其它性能瓶颈,例如跟 aiohttp 结合使用时,瓶颈可能在于 http 解析。


参考博客:uvloop: Blazing fast Python networking

写在最后

我是 HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者 HullQin 授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还独立开发了《合成大西瓜重制版》。还开发了《Dice Crush》参加 Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。

发布于: 刚刚阅读数: 4
用户头像

HullQin

关注

公众号【线下聚会游戏】 2020.10.07 加入

game.hullqin.cn 我做了一些联机桌游网页:支持2-10人联机的UNO、2-4人联机的斗地主、2人联机的五子棋。无需下载,点开即玩!叫上朋友,即刻开局!不看广告,不做任务,享受「纯粹」的游戏!

评论

发布
暂无评论
你必须要会uvloop!让Python asyncio异步编程性能直逼Go协程性能_Go_HullQin_InfoQ写作社区