高频交易系统的核心之一就是速度。“天下武功唯快不破”,快人一等的速度往往是策略赚钱和不赚钱的关键。程序运行速度的提高是一个系统工程,大致可以分为三个层面:硬件,系统内核和交易程序。我们主要从交易程序这个层面来谈谈怎么提高程序的运行速度。
在之前的文章中我们讲了如何通过养成一些好的代码习惯来提高代码的运行速度,对大部分常用的编程语言是有效的。
如何提高交易系统的运行速度(一):养成良好的代码习惯mp.weixin.qq.com以及针对Python pandas库的加速技巧
如何提高交易系统的运行速度(二):Pandas高效优化mp.weixin.qq.com以及常用的C、C++的代码速度优化
如何提高交易系统的运行速度(三):C和C++速度优化mp.weixin.qq.comPython不是一个在速度上有优势的编程语言,但是易用性和丰富的第三方库使得它成为了当今最受欢迎的编程语言之一。在量化领域,很多人都在使用python做数据分析和策略研究。但是对于高频交易,研究对象的数据量很大,所以提高Python代码的运行速度,对提高策略研究效率是有很大助益的。
在网上也有很多介绍提高Python代码的tips,比如:"24式加速你的Python"
在这里,我们将继续介绍一些加快Python运行速度的小技巧,希望对大家能有所帮助。
1. 对字符串避免使用“+”操作
由于python当中的str是不可变对象,在使用“+”来进行字符串连接时,每次连接必须要创建一个新的str对象,如果要连接N个str,那么就要进行 N-1 次的内存申请及copy,所以使用“+”操作是效率低下的。
# 速度低下的代码
2. 尽量避免使用for loop,如果要使用,可以把“.” 操作先在外面定义,尽量使用局部变量
"."操作是耗时的,如果在loop中要多次使用,可以考虑在loop外面定义。但是如果有太多的操作定义在loop外面,代码会显得很冗长,要注意权衡。
# 速度低下的代码
局部变量比全局变量的获取速度要快,所以在逻辑条件允许的情况下,应该尽量优先使用局部变量。让我们来看下面这个例子:
import
这段代码的运行结果是:
3.638981126990984
5.268905453005573
3. dict key计数可以使用try except或者defaultdict
在使用dict的时候,我们常常会遇到要对key计数的情况。比如在订单管理中我们常常需要count某一个订单撤单重发的次数,下面有几种操作方式,可以比较一下运行速度:
import
上面一段代码运行速度对比结果如下:
slow_process:
18.105426316993544
try except:
15.317335735016968
get:
18.27478441299172
defaultdict:
14.626847748993896
由此可见,try except和defaultdict的效率要更高一些。
4. 在运行过程中动态改变函数,达到if的效果
判断语句是会耗时的,特别是判断的条件很多时。但如果判断的分支只需要运行一次时,可以在运行过程中动态改变要运行的函数,达到if的效果
class
运行的结果如下:
example1:
100005 function calls in 0.172 seconds
example2:
100005 function calls in 0.167 seconds
5. 用generator替代 list comprehension
list comprehension会生成整个完整的list,当数据量很大的时候,对内存是不友好的,在这个时候可以考虑使用generator。
import
运行的结果如下:
list:
4.176297603000421
generator:
2.256416424002964
6. 可以调用前进行编译
在使用eval()和exec()运行程序时,可以先通过compile()把要运行的code编译成bytecode来运行,而不是直接call这个code的str,这样可以避免重复编译。同样的,re的pattern matching也可以通过re.compile()先编译好再执行比较和匹配。
import
运行结果:
read1:
1.7358964760205708
read2:
2.1564532320189755
7. 并行
在Python中有几种并行的方案,multi-threads,multi-processing和concurrency. 由于有GIL的存在,multi-threads对运算的性能改进有限。关于并行,有一篇归纳性的文章感兴趣的朋友可以看看。
"python多进程(multiprocessing)归纳"
8.使用优化库
python有很多优秀的优化库来帮助开发者提高代码的运行速度。比如之前的说到的并行,很多时候可以不用开发者自己去调用底层库函数,而通过一些优化库方便实现。
Numba
很多人都听说过numba,它通过LLVM 把python的函数转化成优化后的机器语言来运行。通过神奇的装饰器,numba可以在对python代码改动很小的情况下实现代码运行速度的提升。感兴趣的朋友可以参考:
"A High Performance Python Compiler"
除了numba,还有一些优秀的第三方库可以帮助提升python的运行速度。在这里我们简单介绍几种,供大家参考。
Modin
Modin是加州大学伯克利分校针对pandas运行效率提升开发的一个多进程Dataframe,它具有和pandas相同的API,支持绝大多数的pandas的操作。可以参考:
"Modin"
Dask
Dask是一款用于分析计算的并行计算库。它主要由两部分组成:第一,针对计算优化的动态任务调度, 对交互式计算工作负载进行了优化。第二,“大数据”集合, 像并行数组,数据框和列表一样,它们将通用接口(如NumPy,Pandas或Python迭代器)扩展到大于内存或分布式环境。 这些并行集合运行在动态任务调度器之上。可以参考:
"Dask教程"
"Dask官网"
TVM
TVM是一个用于加速深度学习系统的编译器堆栈。其主要功能是缩小深度学习框架和硬件性能之间的差距。它可以为不同的后端提供高效的端到端编译。有人测试过用TVM方式部署的性能比TensorRT方式有10倍以上的的提升,可以参考这篇文章:
"TensorRT与TVM性能比较(Resnet50)"
对深度学习感兴趣的朋友可以去它的官网了解一下:
"TVM"
9.使用C语言扩展
有一个简单的逻辑:既然python在速度上不擅长,可以把一些繁重的工作交给速度擅长的编程语言来完成。所以出现了很多python/c++接口工具:
"IntegratingPythonWithOtherLanguages"
他们之间的比较可以参考这篇文章:
"浅谈Python程序与C++程序的联合使用"
大家可以按照自己的实际情况和需求选择合适的扩展方式。不过在改写之前,最好先测试出程序的耗时部分,有的放矢。
以上是对Python代码速度优化的一些tips,希望对大家有所帮助。在后面的文章中,我们会继续为大家介绍一些编译优化,数据结构和程序框架方面的知识点,感兴趣的朋友可以关注我们的微信公众号hftquant。
有兴趣的朋友可以登录我们的网站hftquant.com查看高频教程和尝试高频因子研究。
有兴趣的朋友可以继续关注本专栏和公众号hftquant,并登录我们的网站hftquant.com查看高频因子教程。
hftquant.comwww.hftquant.com欢迎关注我的专栏:
hftquant高频系列教程zhuanlan.zhihu.com![b5273e0bb036da496e86777187d7aab5.png](https://i-blog.csdnimg.cn/blog_migrate/a2b2670e13129a576a38ab1573c6f82f.png)
欢迎关注我的微信公众号:hftquant
![2dbaa96b82f9bab41ac5140852e45160.png](https://i-blog.csdnimg.cn/blog_migrate/ff98b25941f7506fc79fe90d59b5be79.jpeg)