Scipy与Numpy的范数性能差异

6

我一直认为scipy.linalg.norm()numpy.linalg.norm()是等价的(之前的scipy版本不支持axis参数,但现在已经支持了)。然而以下简单的例子却表现出显著的不同性能:这是什么原因造成的呢?

In [1]: from scipy.linalg import norm as normsp
In [2]: from numpy.linalg import norm as normnp 
In [3]: import numpy as np
In [4]: a = np.random.random(size=(1000, 2000))

In [5]: %timeit normsp(a)
The slowest run took 5.69 times longer than the fastest. This could mean that an intermediate result is being cached.
100 loops, best of 3: 2.85 ms per loop

In [6]: %timeit normnp(a)
The slowest run took 6.39 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 558 µs per loop

scipy版本为0.18.1,numpy版本为1.11.1。

1个回答

6

查看源代码可以发现,scipy有自己的norm函数,它包装了numpy.linalg.norm或一个BLAS函数,后者速度较慢但处理浮点溢出更好(请参见PR上的讨论)。

然而,在您提供的示例中,似乎scipy没有使用BLAS函数,因此我认为它不应该对您看到的时间差异负责。但是,scipy在调用numpy版本的norm之前会进行一些其他检查。特别是,无限检查a = np.asarray_chkfinite(a)可能会导致性能差异:

In [103]: %timeit normsp(a)
100 loops, best of 3: 5.1 ms per loop

In [104]: %timeit normnp(a)
1000 loops, best of 3: 744 µs per loop

In [105]: %timeit np.asarray_chkfinite(a)
100 loops, best of 3: 4.13 ms per loop

所以看起来 np.asarray_chkfinite 大致解释了评估范数所需时间的差异。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接