Numpy鸿沟与Python鸿沟之间的差异?

时间:2018-03-23 23:38:41

标签: python numpy division elementwise-operations

numpy.divide 与Python斜杠 / 运算符之间有什么相同点和不同点?据我所知,他们的行为相同,都实现了元素划分。 Numpy documentation提及:

  

numpy.divide(x1,x2)......就阵列广播而言,相当于x1 / x2。 ...

暗示np.divide(x1,x2)不是完全等同于x1 / x2。 我运行了以下代码片段来比较它们的速度:

import numpy as np
import time

a = np.random.rand(10000, 10000)
b = np.random.rand(10000, 10000)

tic = time.time()
c = a / b
toc = time.time()
print("Python divide took: ", toc - tic)

tic = time.time()
c = np.divide(a, b)
toc = time.time()
print("Numpy divide took: ", toc - tic)

似乎Python差距通常更快,这使我相信Numpy鸿沟实现了一些额外的花里胡哨。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:7)

这里似乎没有任何实际的性能差异。

当我运行你的代码并交换这两个测试时,无论哪一个更快,都会更快。

当我使用timeit进行正确的基准测试时,他们需要大约相同的时间(/为540毫秒,divide为539毫秒。)

我的猜测是你测量的差异是malloc数组的时间 - 第一个需要这样做,第二个可以重用刚刚释放的内存。

但是让我们来看看来源。 generate_umath.py中的代码会创建实际代码,并将相同的Ufunc(名为numpy.core.umath.divide)分配给np.floor_divide,并PyNumber_FloorDivide分配给np.ndarray }}。 (如果您想知道我在使用floor_dividedivide而不是/floor_divide时查询//的原因,请参阅后面的评论它会为Python 3删除divide,因为它会将其别名为true_divide。)IIRC,实际代码是类型和大小的切换,最终会在{{3}中的一个循环模板中结束}}

因此,除了显式Ufunc包装器代码与内置method-wrapper包装器代码(它与任何不小的数组无关)之间的差异之外,它们最终会在同一个地方。