【发布时间】:2015-08-18 23:04:27
【问题描述】:
为什么下面的L2范数计算会有这么大的速度差异:
a = np.arange(1200.0).reshape((-1,3))
%timeit [np.sqrt((a*a).sum(axis=1))]
100000 loops, best of 3: 12 µs per loop
%timeit [np.sqrt(np.dot(x,x)) for x in a]
1000 loops, best of 3: 814 µs per loop
%timeit [np.linalg.norm(x) for x in a]
100 loops, best of 3: 2 ms per loop
据我所知,所有三个都产生相同的结果。
这里是 numpy.linalg.norm 函数的源代码:
x = asarray(x)
# Check the default case first and handle it immediately.
if ord is None and axis is None:
x = x.ravel(order='K')
if isComplexType(x.dtype.type):
sqnorm = dot(x.real, x.real) + dot(x.imag, x.imag)
else:
sqnorm = dot(x, x)
return sqrt(sqnorm)
编辑:有人建议可以并行化一个版本,但我检查了一下,事实并非如此。所有三个版本都消耗 12.5% 的 CPU(这通常是我的 4 个物理/8 个虚拟核 Xeon CPU 上的 Python 代码的情况。
【问题讨论】:
-
还有几个时间:
[math.sqrt(np.dot(x,x)) for x in a],np.sqrt(np.einsum('ij,ij->i',a,a)) -
主要区别在于解释的 Python 代码和编译后的 C 代码所做的事情。
-
我注意到的一件事是,第一种方法给出的结果比其他方法的精度要低得多。例如第一种方法产生的最终数字是2074.9973494,而后两种方法产生的最终数字是2074.9973493958973。
-
Tris Nefzger,我用 dtype 检查了结果,在所有三种情况下都是 float64。
-
列表和数组有不同的规则来显示浮点数的有效数字。所以显示并没有告诉你很多浮点类型。
标签: python performance numpy