鉴于这里的线程
似乎 numpy 对于超快速计算并不是最理想的。有谁知道在使用 numpy 进行数值计算时我们必须注意什么开销?
鉴于这里的线程
似乎 numpy 对于超快速计算并不是最理想的。有谁知道在使用 numpy 进行数值计算时我们必须注意什么开销?
好吧,取决于你想做什么。例如,XOR 与对数值线性代数感兴趣的人几乎没有关系(由于在下面使用优化的 BLAS/LAPACK 库,numpy 的速度非常快)。
通常,从 numpy 获得良好性能背后的重要思想是一次将解释器的成本分摊到许多元素上。换句话说,将循环从 python 代码(慢)移动到 numpy/BLAS/LAPACK/etc 中某处的 C/Fortran 循环中。内部(快速)。如果您成功完成该操作(称为矢量化),性能通常会非常好。
当然,通过转储 Python 解释器并改用 C++ 等方式,显然可以获得更好的性能。这种方法是否真正成功取决于您在使用 C++ 与 numpy 进行高性能编程方面的表现如何,以及您正在尝试执行什么操作。
任何时候你有一个像 一样的表达式x = a * b + c / d + e
,你最终会得到一个临时数组 for a * b
,一个临时数组 for c / d
,一个用于总和,最后一个分配给结果。这是 Python 类型和运算符重载的限制。*=
但是,您可以使用增强的赋值( ,等)运算符显式地就地执行+=
操作,并确保不会进行复制。
至于 NumPy 在该基准测试中执行速度较慢的具体原因,很难说,但这可能与 Cython/etc 的检查大小、类型编组等的持续开销有关。不必担心。在更大的问题上,您可能会看到它越来越近。
说不上来,但我猜有两个因素:
也许 numpy 正在复制更多的东西?当您避免分配大的临时数组时, weave 通常会更快,但这在这里应该无关紧要。
numpy 在迭代(可能)多维数组时使用了一些开销。这种开销通常与数字运算相比相形见绌,但异或真的非常快,所以真正重要的是开销。
您的子问题:a = sin(x),有多少次往返。
诀窍是将一个 numpy 数组传递给 sin(x),然后整个数组只有一次“往返”,因为 numpy 将返回一个 sin 值数组。此操作不涉及 python for 循环。