我有(或实际上正在开发)一个程序(一些配对交易策略),它执行以下操作:
在这 9 个步骤之后,重新开始,检索另一个训练窗口并执行分析......
我的方法是 - 如果你看到更好的东西,请更正:
1. 从程序中提取尽可能多的函数
2. 通过多个训练和交易窗口循环步骤 1-9
以及我由此产生的问题(受到论坛中许多主题的启发,即如何使您的 python 代码运行得更快
numba.jit()
”所有功能都有意义吗?float64
吗?会发生什么坏处?(目前它们是“标准”数字)请对许多 - 相当概念性的 - 问题表示歉意,但我认为,如果我能理解上述所有“痛点”,它将真正提高我的“逻辑”理解,并且对新的 Python 加入者也非常有益。
非平凡的问题可以产生但简化的答案:
[man*decades]
...简而言之,不要期望阅读一些示例并成为这方面的专家。
第一:糟糕的算法永远不会仅仅通过一些(半)自动转换来改进。智能重构可能会在原生纯 Python 代码(下面的示例)中提高 100% 的性能,但精心设计的代码,与代码执行设备的接近硅特性相匹配,将在其他方面显示出这种努力,作为上述 ~ +100% 性能繁荣的代码改进结果,一旦转换为jit
编译单元,性能几乎相同。这意味着过早的优化在进入精心设计的高性能代码时可能会变得毫无用处。至少你已经被警告过。
python
是一个很棒的工具,我喜欢它几乎无限精确的数学。然而,与计算机科学家相比,同时实现极致精度和极致性能似乎更接近海森堡原理,而且粉丝们也更愿意承认。只是花了很长时间才能把它压缩成几个词段。
numba.jit()
”所有功能都有意义吗?numba
是稳定代码库的好工具,让我们从它开始:
自动化转型的悬而未决的果实很容易用numba.jit()
工具挑选出来。基准测试将帮助您削减几乎所有代码不需要的开销。
如果取决于代码元素,仍在发展的numba.jit()
代码转换器无法转码,那么您就完成了。numba
自从它是最初的版本以来就开始使用它,{ list | dict | class | ... }
对于让代码(自动)转换更接近硅片的任何进一步梦想来说都是杀手。此外,所有引用的函数都必须能够 get numba.jit()
,所以几乎忘记了import
使用 容易翻译的一些高级代码库numba
,如果它们的原始代码没有系统地设计numba
。
float64
吗?float32
除了将[SPACE]
域中内存占用的静态大小减半外,还有一些主要缺点。
一些模块(通常是那些继承自 FORTRAN 数值求解器和类似遗产的模块)自动将任何外部传递的数据转换为它们的本地float64
副本(因此[SPACE]
和[TIME]
惩罚都会增加,超出您的控制范围)。
更好地期待 -[TIME]
域中增加的代码执行惩罚,因为未对齐的单元边界很昂贵(这深入到代码的汇编级别以及 CPU 指令集和缓存层次结构以掌握该级别的所有细节) .
在下面的基准测试中,可能会看到执行速度降低了近 3 倍float32
。
自动矢量化变压器不亚于诺贝尔奖目标。
一些调整可以由聪明而方便的设计师完成。除了微不足道的广播或一些易于设计的 numpy 跨步技巧之外,不要指望在这个领域有任何更复杂的操作可以实现。
专业的代码转换包很昂贵(有人必须支付在许多 [man*years] 中收集的专业知识)并且通常只有在大规模部署时才能调整他们的 ROI。
您很高兴不必将代码设计为以真正的方式运行[PARALLEL]
,而是以“公正”的[CONCURRENT]
方式运行。如果有人说并行,请检查系统是否确实需要满足真正[PARALLEL]
进程调度的所有条件,在大多数情况下,“只是”[CONCURRENT]
调度正是演讲者所要求的(详细信息超出了本文的范围) . Python GIL-stepped 锁定可防止任何基于子流程的工作流拆分,但需要付出代价,因此获得处理的独立性,因为这将奖励您的意图,而无需支付任何额外开销附加成本的惩罚,如果违反开销严格的阿姆达尔定律的规则。
实际成本/效果比必须在各自版本的 python、numba、CPU/缓存架构上进行验证,因此基准测试是确认任何改进的唯一方法(以成本为代价)。
下面的例子显示了一个简单的指数移动平均函数的保存,以几种或多或少的智能方式实现。
def plain_EMA_fromPrice( N_period, aPriceVECTOR ):
...
@numba.jit( "float32[:]( int32, float32[:] )" )
def numba_EMA_fromPrice_float32( N_period, aPriceVECTOR ):
...
@numba.jit( "float32[:]( int32, float32[:] )", nopython = True, nogil = True )
def numba_EMA_fromPrice_float32_nopython( N_period, aPriceVECTOR ):
...
@numba.jit( "float64[:]( int64, float64[:] )" )
def numba_EMA_fromPrice_float64( N_period, aPriceVECTOR ):
...
@numba.jit( "float64[:]( int64, float64[:] )", nopython = True, nogil = True )
def numba_EMA_fromPrice_float64_nopython( N_period, aPriceVECTOR ):
...
def plain_EMA_fromPrice2( N_period, aPriceVECTOR ):
...
@numba.jit( "float32[:]( int32, float32[:] )" )
def numba_EMA_fromPrice2_float32( N_period, aPriceVECTOR ):
...
@numba.jit( "float32[:]( int32, float32[:] )", nopython = True, nogil = True )
def numba_EMA_fromPrice2_float32_nopython( N_period, aPriceVECTOR ):
...
@numba.jit( "float64[:]( int64, float64[:] )" )
def numba_EMA_fromPrice2_float64( N_period, aPriceVECTOR ):
...
@numba.jit( "float64[:]( int64, float64[:] )", nopython = True, nogil = True )
def numba_EMA_fromPrice2_float64_nopython( N_period, aPriceVECTOR ):
...
提高性能
的710 [us] -> 160 [us]
,通过代码重新分解和内存对齐,接下来
DOWNTO-> 12 ~ 17 [us]
通过numba.jit()
:
>>> aPV_32 = np.arange( 100, dtype = np.float32 )
>>> aPV_64 = np.arange( 100, dtype = np.float32 )
>>> aClk.start();_ = plain_EMA_fromPrice( 18, aPV_32 );aClk.stop()
715L
723L
712L
722L
975L
>>> aClk.start();_ = plain_EMA_fromPrice( 18, aPV_64 );aClk.stop()
220L
219L
216L
193L
212L
217L
218L
215L
217L
217L
>>> aClk.start();_ = numba_EMA_fromPrice_float32( 18, aPV_32 );aClk.stop()
199L
15L
16L
16L
17L
13L
16L
12L
>>> aClk.start();_ = numba_EMA_fromPrice_float64( 18, aPV_64 );aClk.stop()
170L
16L
16L
16L
18L
14L
16L
14L
17L
>>> aClk.start();_ = numba_EMA_fromPrice_float64_nopython( 18, aPV_64 );aClk.stop()
16L
17L
17L
16L
12L
16L
14L
16L
15L
>>> aClk.start();_ = plain_EMA_fromPrice2( 18, aPV_32 );aClk.stop()
648L
654L
662L
648L
647L
>>> aClk.start();_ = plain_EMA_fromPrice2( 18, aPV_64 );aClk.stop()
165L
166L
162L
162L
162L
163L
162L
162L
>>> aClk.start();_ = numba_EMA_fromPrice2_float32( 18, aPV_32 );aClk.stop()
43L
45L
43L
41L
41L
42L
>>> aClk.start();_ = numba_EMA_fromPrice2_float64( 18, aPV_64 );aClk.stop()
17L
16L
15L
17L
17L
17L
12L
>>> aClk.start();_ = numba_EMA_fromPrice2_float64_nopython( 18, aPV_64 );aClk.stop()
16L
15L
15L
14L
17L
15L
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句