我已经写了一个函数来在磁盘上创建均匀间隔的点,因为它经常运行,并且在相对较大的数组上运行,所以我认为numba
的应用程序会显着提高速度。然而,在运行一个快速测试时,我发现numba
函数的速度要慢两倍多。
有没有办法找出是什么减慢了numba
函数的速度?
函数如下:
@njit(cache=True)
def generate_points_turbo(centre_point, radius, num_rings, x_axis=np.array([-1, 0, 0]), y_axis=np.array([0, 1, 0])):
"""
Generate uniformly spaced points inside a circle
Based on algorithm from:
http://www.holoborodko.com/pavel/2015/07/23/generating-equidistant-points-on-unit-disk/
Parameters
----------
centre_point : np.ndarray (1, 3)
radius : float/int
num_rings : int
x_axis : np.ndarray
y_axis : np.ndarray
Returns
-------
points : np.ndarray (n, 3)
"""
if num_rings > 0:
delta_R = 1 / num_rings
ring_radii = np.linspace(delta_R, 1, int(num_rings)) * radius
k = np.arange(num_rings) + 1
points_per_ring = np.rint(np.pi / np.arcsin(1 / (2*k))).astype(np.int32)
num_points = points_per_ring.sum() + 1
ring_indices = np.zeros(int(num_rings)+1)
ring_indices[1:] = points_per_ring.cumsum()
ring_indices += 1
points = np.zeros((num_points, 3))
points[0, :] = centre_point
for indx in range(len(ring_radii)):
theta = np.linspace(0, 2 * np.pi, points_per_ring[indx]+1)
points[ring_indices[indx]:ring_indices[indx+1], :] = ((ring_radii[indx] * np.cos(theta[1:]) * x_axis[:, None]).T
+ (ring_radii[indx] * np.sin(theta[1:]) * y_axis[:, None]).T)
return points + centre_point
它的名字是这样的:
centre_point = np.array([0,0,0])
radius = 1
num_rings = 15
generate_points_turbo(centre_point, radius, num_rings )
如果有人知道为什么在编译numba
时函数会变慢,或者如何找出numba
函数的瓶颈是什么,那就太好了。
更新:可能的计算机特定大小依赖性
看起来numba
函数正在工作,但是它的速度更快和更慢之间的交叉可能是硬件特定的。
%timeit generate_points(centre_point, 1, 2)
99.5 µs ± 932 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit generate_points_turbo(centre_point, 1, 2)
213 µs ± 8.4 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%timeit generate_points(centre_point, 1, 20)
647 µs ± 11.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%timeit generate_points_turbo(centre_point, 1, 20)
314 µs ± 8.74 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%timeit generate_points(centre_point, 1, 200)
11.9 ms ± 375 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit generate_points_turbo(centre_point, 1, 200)
7.9 ms ± 243 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
在大约12-15次振铃后,numba
函数(*_turbo)开始在我的机器上变得类似或更快的速度,但在更大尺寸下的性能增益小于预期。但看起来它实际上是工作的,只是功能的某些部分严重依赖于大小。
1条答案
按热度按时间ctzwtxfj1#
我摆脱了你所有的换位/ newaxis / 3D的东西,你没有使用,并得到了一个x20的提升相比,你原来的解决方案。我用
prange
替换了range
,因为你不在乎你的点是按什么顺序计算的。