【发布时间】:2019-03-29 12:18:55
【问题描述】:
我知道 numba 会产生一些开销,并且在某些情况下(非密集计算)它会比纯 python 慢。但我不知道在哪里画线。是否可以使用算法复杂度的顺序来确定在哪里?
例如,在此代码中添加两个比 5 短的数组 (~O(n)),纯 python 更快:
def sum_1(a,b):
result = 0.0
for i,j in zip(a,b):
result += (i+j)
return result
@numba.jit('float64[:](float64[:],float64[:])')
def sum_2(a,b):
result = 0.0
for i,j in zip(a,b):
result += (i+j)
return result
# try 100
a = np.linspace(1.0,2.0,5)
b = np.linspace(1.0,2.0,5)
print("pure python: ")
%timeit -o sum_1(a,b)
print("\n\n\n\npython + numba: ")
%timeit -o sum_2(a,b)
更新:我正在寻找类似here 的指南:
“一般准则是为不同的数据大小和算法选择不同的目标。“cpu”目标适用于小数据大小(大约小于 1KB)和低计算强度算法。它的开销最少. “并行”目标适用于中等数据大小(大约小于 1MB)。线程增加了小延迟。“cuda”目标适用于大数据大小(大约大于 1MB)和高计算强度算法。将内存传入和传出 GPU 会增加大量开销。”
【问题讨论】:
-
在测量 numba 的性能时,您需要在测量前调用该函数一次。因为在第一次调用期间,函数被编译,这需要很多时间。你也可以试试
@numba.autojit。 -
在我的机器上 python: 3.31 µs, numba: 589 ns, 虽然不是很大的改进。至于您的问题,我真的认为这与复杂性并没有真正的关系,它可能取决于您正在执行的操作类型。另一方面,您仍然可以绘制 python/numba 比较,以查看给定函数发生偏移的位置。我也对一个玩具示例做了一些测试,向数组中的所有元素添加一个,numba 总是比 python 快,并且类似于 cython。
-
@cglacet 感谢您的回复。是的,我在基准测试之前运行它,(毕竟它只是及时编译:))。关于您的第二条评论
@numba.autojit不会重现您所得到的。对于阵列 len 5,它们的运行时间几乎相同。也许我没有把它放在正确的位置。我试过这个@numba.jit('float64[:](float64[:],float64[:])') -
您真的要显式声明非连续数组,同时提供连续数组进行测试吗?为输出声明一个数组也很奇怪,因为结果是一个标量。对于这类问题,您通常会让 Numba 确定数组声明,然后添加一个 fastmath 标志
@numba.njit(fastmath=True)(使 SIMD-Vectorization 成为可能),也许还有一个 cache=True 用于缓存已编译的函数。已更正,该函数在任何情况下都应该比@MSeifert 的numpy_methods方法运行得更快。
标签: python python-3.x performance numba