使用 numba.jit 加速代码
Accelerating code using numba.jit
我正在尝试使用 numba.jit
加速 python 程序。
我的程序的一个函数将 float
数组和一个标量相乘,标量始终是整数。
import numpy
myarray = numpy.array([0.2,0.26,0.45,0.78],dtype=float)
def multiply(array, scalar):
newarray = array * scalar
return newarray
newarray = multiply(myarray,5)
当我 numba.jit()
我的函数具有以下签名时,函数运行速度慢了一个数量级:
fastmultiply = numba.jit("f4[:](f4[:],int8)")(multiply)
这是因为我声明了错误的数据类型:f4[:]
和 int8
?
或者我的函数编码方式不允许使用 numba.jit()
进行加速?
工作量经济 v/s 生成的 jit
代码重用量
JIT 在某些情况下可以提供帮助,其中大量的重用证明了即时编译的成本。
代码的第一个 运行 因此需要更长的时间,因为 .jit()
编译器处理源代码。
注意工作的经济性 - 对于 "short" 代码,这可能比最终的 jit 编译产品花费几个数量级的时间,因此调整这样的初始只有在有数百万个重复使用案例时,机会成本惩罚才可能变得合理。
对于很多 "more computationally intensive" 代码,通常是非平凡的卷积、迭代再处理方法等,即使对于单个案例,jit 编译的成本也可能变得合理。
@numba.jit()
signatures
好吧,这是一个单独的主题,错误的类型可能会挂起您的处理。
显式 .jit()
签名或 .autojit()
? 这就是哈姆雷特的困境。
好吧,这取决于您的喜好。 定量证据 应收集关于两种方法的初始调用/重复使用调用的持续时间,并根据重复使用调用的预期数量(成本/收益不平等)来决定。
#numba.jit( 'f4[:](i4,f4[:])' ) # .float32 # [DONE] PERF.ToDo.MS:
#numba.jit( 'f4[:](i8,f8[:])' ) # .float32 # .float64 # [DONE] PERF.ToDo.MS:
@jit( 'f8[:](i8,f8[:])' ) # .float64 # [DONE] PERF.ToDo.MS:
def numba_EMA_fromPrice( N_period, aPriceVECTOR ): # TEST: perf (non)-jit Stopwatch.start();;Stopwatch.stop()
...
# @numba.jit [usec]----------------------------------------- PERFORMANCE PROFILING
aClk.start();numba_EMA_fromPrice( 8, price_H4_CLOSE );aClk.stop()
Out[112]: 160814L # 1. JIT-compile
Out[113]: 331L # re-use 0.3xy[ms] v/s 11.5[ms] CPython
Out[114]: 311L
Out[115]: 324L
#
# @numba.guvectorize()
# @numba.jit( nogil = True ) # JIT w/o GIL-lock w/ multi-CORE ** WARNING: ThreadSafe / DataCoherency measures **
aClk.start();numba_EMA_fromPrice( 8, price_H4_CLOSE );aClk.stop()
Out[126]: 149929L # 1. JIT-compile
Out[127]: 284L # re-use 0.28[ms] v/s 11.5[ms] CPython
Out[128]: 256L
autojit()
个签名的额外成本,需要 analyzing/adapting,可能会扭曲成本/收益不平等的边缘。
.jit()
显式签名的维护 可能会令人头疼。
小心:
先,np.float
是不是f4
|>>> np.arange( 2, dtype = float ).dtype
dtype('float64')
下一个,有些情况(np.nan_to_num()
就是其中之一),可能会收到 "静默" 将 dtype
向上转换为 np.float64
,这可能会导致令人头疼的寻找 dtype
与 numba.jit()
显式冲突的地方签名。
我正在尝试使用 numba.jit
加速 python 程序。
我的程序的一个函数将 float
数组和一个标量相乘,标量始终是整数。
import numpy
myarray = numpy.array([0.2,0.26,0.45,0.78],dtype=float)
def multiply(array, scalar):
newarray = array * scalar
return newarray
newarray = multiply(myarray,5)
当我 numba.jit()
我的函数具有以下签名时,函数运行速度慢了一个数量级:
fastmultiply = numba.jit("f4[:](f4[:],int8)")(multiply)
这是因为我声明了错误的数据类型:f4[:]
和 int8
?
或者我的函数编码方式不允许使用 numba.jit()
进行加速?
工作量经济 v/s 生成的 jit
代码重用量
JIT 在某些情况下可以提供帮助,其中大量的重用证明了即时编译的成本。
代码的第一个 运行 因此需要更长的时间,因为 .jit()
编译器处理源代码。
注意工作的经济性 - 对于 "short" 代码,这可能比最终的 jit 编译产品花费几个数量级的时间,因此调整这样的初始只有在有数百万个重复使用案例时,机会成本惩罚才可能变得合理。
对于很多 "more computationally intensive" 代码,通常是非平凡的卷积、迭代再处理方法等,即使对于单个案例,jit 编译的成本也可能变得合理。
@numba.jit()
signatures
好吧,这是一个单独的主题,错误的类型可能会挂起您的处理。
显式 .jit()
签名或 .autojit()
? 这就是哈姆雷特的困境。
好吧,这取决于您的喜好。 定量证据 应收集关于两种方法的初始调用/重复使用调用的持续时间,并根据重复使用调用的预期数量(成本/收益不平等)来决定。
#numba.jit( 'f4[:](i4,f4[:])' ) # .float32 # [DONE] PERF.ToDo.MS:
#numba.jit( 'f4[:](i8,f8[:])' ) # .float32 # .float64 # [DONE] PERF.ToDo.MS:
@jit( 'f8[:](i8,f8[:])' ) # .float64 # [DONE] PERF.ToDo.MS:
def numba_EMA_fromPrice( N_period, aPriceVECTOR ): # TEST: perf (non)-jit Stopwatch.start();;Stopwatch.stop()
...
# @numba.jit [usec]----------------------------------------- PERFORMANCE PROFILING
aClk.start();numba_EMA_fromPrice( 8, price_H4_CLOSE );aClk.stop()
Out[112]: 160814L # 1. JIT-compile
Out[113]: 331L # re-use 0.3xy[ms] v/s 11.5[ms] CPython
Out[114]: 311L
Out[115]: 324L
#
# @numba.guvectorize()
# @numba.jit( nogil = True ) # JIT w/o GIL-lock w/ multi-CORE ** WARNING: ThreadSafe / DataCoherency measures **
aClk.start();numba_EMA_fromPrice( 8, price_H4_CLOSE );aClk.stop()
Out[126]: 149929L # 1. JIT-compile
Out[127]: 284L # re-use 0.28[ms] v/s 11.5[ms] CPython
Out[128]: 256L
autojit()
个签名的额外成本,需要 analyzing/adapting,可能会扭曲成本/收益不平等的边缘。
.jit()
显式签名的维护 可能会令人头疼。
小心:
先,np.float
是不是f4
|>>> np.arange( 2, dtype = float ).dtype
dtype('float64')
下一个,有些情况(np.nan_to_num()
就是其中之一),可能会收到 "静默" 将 dtype
向上转换为 np.float64
,这可能会导致令人头疼的寻找 dtype
与 numba.jit()
显式冲突的地方签名。