【发布时间】:2019-06-28 12:25:45
【问题描述】:
这是基于this question 2018-10 提出的。
考虑以下代码。三个简单的函数来计算 NumPy 3D 数组 (1000 × 1000 × 1000) 中的非零元素。
import numpy as np
def f_1(arr):
return np.sum(arr > 0)
def f_2(arr):
ans = 0
for val in range(arr.shape[0]):
ans += np.sum(arr[val, :, :] > 0)
return ans
def f_3(arr):
return np.count_nonzero(arr)
if __name__ == '__main__':
data = np.random.randint(0, 10, (1_000, 1_000, 1_000))
print(f_1(data))
print(f_2(data))
print(f_3(data))
我机器上的运行时(Python 3.7.?、Windows 10、NumPy 1.16.?):
%timeit f_1(data)
1.73 s ± 21.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit f_2(data)
1.4 s ± 1.36 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit f_3(data)
2.38 s ± 956 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
所以,f_2() 的运行速度比 f_1() 和 f_3() 快。但是,较小的data 并非如此。问题是——为什么会这样?是 NumPy、Python 还是其他?
【问题讨论】:
-
您正在声明一个 8Gb 阵列,它不适合许多台式机或笔记本电脑,因此您正在隐式测试缓存行为。 np.int64 类型的 3D numpy 数组(1000 × 1000 × 1000 立方体)是 10^9 个元素,每个元素 8 个字节。因此,这将归结为 8Gb 整数数组是否适合/被缓存/等在您的特定机器上。由于它不适合许多台式机或笔记本电脑,因此如果您不想测试缓存,请改用 100 × 100 × 100 的尺寸,即 8Mb。
-
另外,为了确定这一点,请在
np.random.randint调用之前设置随机种子。 -
@Barker 您似乎忽略了秒和毫秒之间的差异。
标签: python performance numpy