Scipy的关联功能很慢

Scipy's correlate function is slow

我已经使用 numpy/scipy 比较了 convolving/correlating 两个信号的不同方法。事实证明,速度存在巨大差异。我比较了以下方法:

现在我当然明白fftconvolve和其他两个函数之间有相当大的区别。我不明白的是为什么 sps.correlate 比 np.correlate 慢得多。有人知道为什么 scipy 使用的实现速度慢得多吗?

为了完整起见,这里是生成情节的代码:

import time

import numpy as np
import scipy.signal as sps

from matplotlib import pyplot as plt


if __name__ == '__main__':

    a = 10**(np.arange(10)/2)
    print(a)

    results = {}
    results['np.correlate'] = np.zeros(len(a))
    results['sps.correlate'] = np.zeros(len(a))
    results['sps.fftconvolve'] = np.zeros(len(a))

    ii = 0
    for length in a:

        sig = np.random.rand(length)

        t0 = time.clock()
        for jj in range(3):
            np.correlate(sig, sig, 'full')
        t1 = time.clock()
        elapsed = (t1-t0)/3

        results['np.correlate'][ii] = elapsed

        t0 = time.clock()
        for jj in range(3):
            sps.correlate(sig, sig, 'full')
        t1 = time.clock()
        elapsed = (t1-t0)/3

        results['sps.correlate'][ii] = elapsed

        t0 = time.clock()
        for jj in range(3):
            sps.fftconvolve(sig, sig, 'full')
        t1 = time.clock()
        elapsed = (t1-t0)/3

        results['sps.fftconvolve'][ii] = elapsed

        ii += 1

    ax = plt.figure()
    plt.loglog(a, results['np.correlate'], label='np.correlate')
    plt.loglog(a, results['sps.correlate'], label='sps.correlate')
    plt.loglog(a, results['sps.fftconvolve'], label='sps.fftconvolve')
    plt.xlabel('Signal length')
    plt.ylabel('Elapsed time in seconds')

    plt.legend()
    plt.grid()

    plt.show()

根据文档,numpy.correlate 是为一维数组设计的,而 scipy.correlate 可以接受 ND 数组。

scipy 实现更通用,因此更复杂,似乎确实会产生额外的计算开销。您可以比较 numpy and scipy 实现之间的 C 代码。

另一个区别可能是,例如,现代处理器上的编译器更好地矢量化了 numpy 实现,等等。