【问题标题】:Speed up mathematical calculations in Python加快 Python 中的数学计算
【发布时间】:2015-07-30 18:07:37
【问题描述】:

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

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

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

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

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

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

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

非常感谢。

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

【问题讨论】:

  • 我建议在深入研究微观优化之前先寻找宏观优化:您确定程序需要循环那么多次吗?嵌套循环每次都需要执行这个计算吗?有时可以保存其中一些计算以供以后参考吗?
  • 也许在这里试试codereview.stackexchange.com
  • @BJH 请记住,代码审查需要完整的工作代码才能被接受。这个 sn-p 是example code,很可能不会被很好地接收。如果您在那里发布整个场景(包括用例),那么我们非常欢迎它。 :)
  • 取幂通常很昂贵。而不是(p-1) * c**(p-1)/(v_dt+c)**p,看看(p-1) * (c/(v_dt+c))**p / c是否更快。
  • 当您没有为该行代码提供任何上下文时,很难提出优化建议。哪些参数因调用而异?您也许可以预先计算一些该表达式。你用结果做什么?据我们所知,可能有一些方法可以完全跳过该中间数组的计算。

标签: python arrays math numpy cython


【解决方案1】:

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

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 已经调整为有效地执行这样的数学运算。

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

【讨论】:

    【解决方案2】:

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

    快速总结:

    • 最有趣的是,对于小型数组(

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

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

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

    例如,您可以使用(a * b * c) * vector 代替执行 3 次向量乘法的 (a * (b * (c * vector))),它执行 1 次。

    【讨论】:

      猜你喜欢
      • 2016-12-24
      • 1970-01-01
      • 2011-02-22
      • 1970-01-01
      • 2018-07-08
      • 2013-12-18
      • 2014-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多