同版本numpy下,为何Python2的numpy.fft.fft比Python3更快?
为什么Python 2的numpy.fft.fft比Python 3更快?
这是个很值得探究的性能差异问题,结合你提供的测试环境和代码,主要可以从以下几个核心角度来解释:
1. NumPy编译优化与底层库绑定差异
虽然你用的NumPy版本都是1.19.1,但针对Python 2和Python 3的编译配置、依赖库绑定可能完全不同:
- MacOS自带的Python 2.7通常是用Apple自家的Clang编译器编译的,并且默认会优先链接系统的
Accelerate框架(里面包含了针对Apple硬件深度调优的FFT实现)。 - 而你的Python 3.7如果是通过Homebrew、pyenv等方式安装的,NumPy可能是用GCC或不同版本的Clang编译的,甚至可能没有启用
Accelerate框架,转而使用纯软件实现的FFTW库,这会直接导致FFT计算速度下降。
你可以在两个环境里运行np.show_config(),查看fftw或accelerate相关的配置项,就能快速验证这一点。
2. 数组内存管理与类型处理的细微差别
你的测试数组是(1920, 1080, 2)的大尺寸数组,FFT计算对内存连续性、缓存命中率非常敏感:
- Python 2的NumPy在数组内存对齐、类型转换的处理上,可能和Python 3的版本有细微差异。比如Python 3的NumPy为了更好的类型安全性,在数组传递到底层C函数前会多一些检查步骤,或者内存布局的默认策略有所调整,导致缓存效率降低,进而拖慢FFT速度。
3. Python解释器的底层开销差异
虽然FFT的核心计算是用C实现的,但从Python层调用FFT的过程中,还是会涉及到少量解释器层面的操作:
- Python 3的解释器在类型检查、函数调用机制上比Python 2有更多的安全校验和抽象层,这些额外的开销在单次调用中可能不明显,但处理大尺寸数组时,累积起来就会体现出可观测的差异。
验证建议
如果你想进一步确认原因,可以试试这些操作:
- 用更小的数组(比如
(100,100,2))重复测试,看性能差异的比例是否一致,排除大内存带来的影响。 - 手动编译Python 3版本的NumPy,启用
Accelerate框架支持,对比编译前后的性能变化。 - 测试
scipy.fftpack.fft的性能差异,看是否和numpy.fft.fft的趋势一致,判断是NumPy本身的问题还是底层FFT库的问题。
内容的提问来源于stack exchange,提问作者Outro
相关产品推荐
相关产品推荐

