理解 asyncio 来构建高性能 Python 网络程序 - Ricequant米筐量化

本文介绍了 Python 的 asyncio 库如何帮助编写高性能的 I/O 密集型程序,特别是对于 RQData 这样的金融数据 API 服务。asyncio 提供了异步和协程功能,简化了网络程序的编写。通过示例,解释了如何使用 async/await 关键字,EventLoop,Future/Promise,以及 Task 对象来管理控制流。最后总结了 asyncio 的主要特点,包括协程链、事件循环的工作原理。
摘要由CSDN通过智能技术生成

Python 是一门上手快、优雅简洁的编程语言,其多范式、丰富的标准库和第三方库能够让编程人员把精力集中在逻辑和思维方法上,而不用去担心复杂语法、类型系统等外在因素,从而高效地达成自己的编程目标。Python 抽象层次非常高,这帮助我们更好更快地完成编程,但也屏蔽了很多细节,程序员也无法精确控制计算机底层的资源,代码性能优化就变得比较复杂。很多资深的程序员可能会觉得 Python 性能不够好,无法编写高性能的程序,其实这句话也不全对。对于计算密集型的程序,Python 可以通过扩展的形式使得核心计算直接调用其它语言(通常是 C 语言)写的包。比如说近期流行的机器学习所使用的 CUDA 技术,Nvidia 就在官网发表了一篇文章专门讲如何通过 Python 使用 CUDA 技术。还有科学计算库 Numpy,也是有代表的 Python 高性能的第三方库。如果第三方库不能满足我们,还可以通过 Cython 这种有着类 Python 语法的工具来生成 Python 的 C 语言扩展库,直接给我们的程序加速。这些技术使得 Python 也可以有高性能的计算能力,但是本身核心代码并不是用 Python 写的,所以在本文中不关注这些技术。我们在本文中主要讨论另一种情况,如何写 I/O 密集型的高性能 Python 程序

RQData 就是一个典型的需要高 I/O 性能的产品。RQData 是米筐为专业投资者提供便利易用的金融数据 API 。用户使用 RQData 客户端工具包 rqdatac,通过网络的方式调取存在远程的金融数据(云端或本地取决于实施方式)。RQData 提供了非常多的 Python API,方便投资者调取全市场的金融数据。这些 API 包含了股票、期货、现货、期权、可转债、场内基金、风险因子、财务因子等类型,而这些数据最重要的特性就是数据量大。RQData 日常面临着每天数亿次对于总量约为 1T 数据的随机调取。这些调取所需返回的数据量往往也相当庞大,例如十年全 A 股的日线数据大约会返回 1 个 G 的数据。在这样的压力下,我们仍希望用户在使用 RQData 的时候就像浏览器下载文件一样快,这些需求在 RQData 中都是用 Python 通过 asyncio 模块完成的。接下来我们一起由浅入深地学习一下 asyncio 。

 

Asyncio 初识

asyncio 是 Python 3.5 中引入的一个库, 目的是方便编写网络应用程序。一个简单的以 RQData 服务端为例的网络处理的核心代码基本如下(简化了 API 的业务逻辑):

图片

上面的代码建构了一个简单的服务端应用,它接收到用户的连接后,直接返回用户输入的数据。这个程序非常简单,却能体现出 asyncio 的魅力。我们构建的程序非常像传统的网络程序。和传统的网络程序相比,我们改动了三处

  • 用了 async 关键字定义了一个协程函数,而不是一个普通的函数。
  • 相比于传统的阻塞的函数调用 , 在调用 async 关键字定义的函数前加入了 await 。
  • 没有使用 socket 定义的方法,而是换成了 asyncio 中 EventLoop 定义的 async 协程函数。

仅仅多了 async 和 await 两个关键字,我们就享受了协程的优势。协程让我们不用担心过多的线程导致操作系统调度占用了太多的 CPU 时间,我们的程序可以运行在一个 CPU 上,享受 CPU 的高速缓存,减少 CPU 缓存同步的开销,而且我们的代码非常容易理解,几乎和传统的网络程序没有什么区别。

 

异步与协程

asyncio 全称 asynchronous I/O ——异步输入输出。相对于同步,异步函数会在调用时不等待 I/O 操作完成,I/O 结果通过回调的方式交给调用者。举个打电话的例子,如果对方忙线,同步函数会一起挂起,直到对方接听了我的电话;异步函数则是留言到语音信箱,通知对方在完成了上一通电话后,再给

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值