在 Python 中加快数学计算

Speed up mathematical calculations in Python

我目前正在尝试优化一个程序。主要瓶颈实际上是在 numpy 数组上运行的相当简单的单行计算,例如:

(p-1) * c**(p-1)/(v_dt+c)**p

(这里的 p & c 是浮点数,v_dt 一个 ~500 长的浮点数 numpy 数组)

这个计算在我的机器上大约需要 1/50 秒

(使用 timeit 计时:1000 次循环,最好的 3 次:每次循环 21.8 毫秒)

问题是这个小函数(我还有其他几个类似的函数)在一个运行大约 100 次的循环中每次迭代被调用大约 500 次。所以这一行突然让我的运行时间增加了 20 分钟。

在 python 中加速数学计算的最佳方法是什么? python 技巧可以完成多少?我已经研究了 c_types 和可能的 Cython,但我该如何使用它们?我是否需要为这些瓶颈函数编写 C 代码,或者我可以使用已经编译的库(我没有使用 C 的经验)。

非常感谢。

编辑: 我忘了说,我已经在研究循环的并行化选项,但仍然想直接加速这些瓶颈函数,因为这是性能关键代码

在我天真的测试中,这看起来并不那么昂贵:

In [65]: p,c =2.,2.
In [66]: v_dt=np.ones(500)*1.5
In [67]: x=(p-1)*c**(p-1)/(v_dt+c)**p
In [68]: timeit x=(p-1)*c**(p-1)/(v_dt+c)**p
10000 loops, best of 3: 23.5 µs per loop

pc

不同,稍微贵一点
In [77]: p,c =2.123,1.324
In [78]: timeit x=(p-1)*c**(p-1)/(v_dt+c)**p
10000 loops, best of 3: 95.9 µs per loop

大部分时间在向量求幂:

In [82]: %timeit v_dt**p
10000 loops, best of 3: 75.5 µs per loop

(这是在 Windows7 年份的 Centron 笔记本电脑上)。

这不是 cython 或其他自己动手编译的代码可以做得更好的计算。 numpy 已经调整为可以高效地执行这样的数学运算。

我认为你需要放眼大局。为什么需要如此频繁地调用它?你能用更大的数组调用更少的次数吗?

我认为 this article 令人惊讶和有趣。

快速总结:

  • 最有趣的是,对于小数组(<150 个元素),他发现 Python 实际上比 Numpy 更快。我想更少的开销。

  • 您也可以用 C++ 编写内部循环,然后通过 Python 调用它。

  • 您可以查看 Numba,这似乎是一种非常简单的加速简单计算的方法。

最后,我通过重组函数实现了加速,这样矢量部分只被触及一次。

举个例子,您可以 (a * b * c) * vector 而不是执行 3 次向量乘法的 (a * (b * (c * vector))),它执行一次。