我运行测试sqript。它使用基于FFTW的numpy.fft.fft(),anfft.fft()和基于FFTW的pyfftw.interfaces.numpy_fft.fft()。
这是我的测试脚本的来源:
import numpy as np
import anfft
import pyfftw
import time
a = pyfftw.n_byte_align_empty(128, 16, 'complex128')
a[:] = np.random.randn(128) + 1j*np.random.randn(128)
time0 = time.clock()
res1 = np.fft.fft(a)
time1 = time.clock()
res2 = anfft.fft(a)
time2 = time.clock()
res3 = pyfftw.interfaces.numpy_fft.fft(a,threads=50)
time3 = time.clock()
print 'Time numpy: %s' % (time1 - time0)
print 'Time anfft: %s' % (time2 - time1)
print 'Time pyfftw: %s' % (time3 - time2)
我得到了这些结果:
Time numpy: 0.00154248116307
Time anfft: 0.0139805208195
Time pyfftw: 0.137729374893
anfft库在大数据上产生更快的fft,但是pyfftw呢?为什么这么慢?
答案 0 :(得分:5)
在这种情况下,产生比CPU内核更多的线程不会增加性能,并且可能会因为切换线程的开销而使程序变慢。 50个线程完全矫枉过正。
尝试使用一个主题进行基准测试。
答案 1 :(得分:2)
可能是pyFFTW实际上花费了大部分时间来规划变换。尝试在pyfftw fft调用中包含例如planner_effort='FFTW_ESTIMATE'
,并查看它如何影响性能。
答案 2 :(得分:2)
这里的问题是使用numpy_fft
接口的开销。首先,您应该使用pyfftw.interfaces.cache.enable()
启用缓存,然后使用timeit
测试结果。即使使用缓存,如果使用原始接口,使用不存在的接口也会产生固定的开销。
在我的机器上,在128个长度的阵列上,接口的开销仍然会使其减慢超过numpy.fft
。随着长度的增加,这种开销变得不那么重要了,所以比如一个16000长的数组,numpy_fft
接口更快。
您可以调用tweaks来加速接口端的速度,但这些不太可能对您的情况产生很大影响。
在所有情况下获得最快变换的最佳方法是直接使用FFTW
object,最简单的方法是使用builders函数。在你的情况下:
t = pyfftw.builders.fft(a)
timeit t()
有了这个,我得到的pyfftw比带有128个长度数组的np.fft
快15倍。