【发布时间】:2013-08-06 22:26:01
【问题描述】:
Numba 似乎是加速数字代码执行的绝佳解决方案。但是,当对数组进行赋值时,Numba 似乎比标准 Python 代码慢。考虑这个例子,比较四个替代方案,有/没有 Numba,写入一个数组/标量:
(故意将计算保持非常简单,以专注于问题,即分配给标量与分配给数组单元格)
@autojit
def fast_sum_arr(arr):
z = arr.copy()
M = len(arr)
for i in range(M):
z[i] += arr[i]
return z
def sum_arr(arr):
z = arr.copy()
M = len(arr)
for i in range(M):
z[i] += arr[i]
return z
@autojit
def fast_sum_sclr(arr):
z = 0
M = len(arr)
for i in range(M):
z += arr[i]
return z
def sum_sclr(arr):
z = 0
M = len(arr)
for i in range(M):
z += arr[i]
return z
使用 IPython 的 %timeit 评估我得到的四个备选方案:
In [125]: %timeit fast_sum_arr(arr)
100 loops, best of 3: 10.8 ms per loop
In [126]: %timeit sum_arr(arr)
100 loops, best of 3: 4.11 ms per loop
In [127]: %timeit fast_sum_sclr(arr)
100000 loops, best of 3: 10 us per loop
In [128]: %timeit sum_sclr(arr)
100 loops, best of 3: 2.93 ms per loop
sum_arr,不是用 Numba 编译的,比用 Numba 编译的 fast_sum_arr 快两倍多。另一方面,用 Numba 编译的 fast_sum_sclr 比没有用 Numba 编译的 sum_sclr 快两个数量级以上。
所以 Numba 在加速 sum_sclr 的任务上表现得非常好,但实际上使 sum_arr 执行得更慢。 sum_sclr 和 sum_arr 之间的唯一区别是前者分配给标量,而后者分配给数组单元。
不知道有没有关系,不过最近在博客http://www.phi-node.com/看到了以下内容:
“事实证明,当 Numba 遇到它不直接支持的任何构造时,它会切换到(非常)慢的代码路径。”
博客作者使用 if 语句而不是 Python 的 max() 让 Numba 执行得更快。
对此有何见解?
谢谢,
FS
【问题讨论】:
-
我不明白你的循环应该做什么。这不是有效的
z[1:] += arr[1:],还是因为z和r具有相同的值,z[1:] *= 2?我希望这比任何显式循环都快得多,但我不一定希望编译器能够分辨出来。