我正在尝试使用 numba.jit
来加速python程序。
我程序的一个函数乘以一个float
s数组和一个标量,它总是一个整数。
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()
?
答案 0 :(得分:0)
jit
- 代码重用的数量JIT 可以提供帮助,因为重复使用的数量证明了即时编译的成本。
因为.jit()
编译器处理源代码,所以代码的第一次运行会变得更长。
谨防经济努力 - 对于"短"代码这可能比最终的jit编译产品要长几个数量级,因此只有拥有数百万次重用案例时,调整这样的初始机会成本惩罚才可能变得合理。
对于更多计算密集型的"代码,通常是一个非平凡的卷积,迭代重新处理方法等,即使对于单个案例,jit-compilation的成本也可能是合理的。
@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()
签名的额外费用可能会影响成本/收益不平等的优势。
.jit()
明确签名的维护可能会让人头疼。
小心点:
首先,np.float
不 f4
|>>> np.arange( 2, dtype = float ).dtype
dtype('float64')
下一步,有些情况(np.nan_to_num()
就是其中之一),可能会收到" 默默地"将dtype
提升为np.float64
,这可能会导致头痛,因为找到了dtype
与numba.jit()
显式签名发生冲突的地方。