用Python加速数学计算

用Python加速数学计算,python,arrays,math,numpy,cython,Python,Arrays,Math,Numpy,Cython,我目前正在尝试优化一个程序。主要的瓶颈实际上是在numpy阵列上运行的相当简单的单线计算,例如: (p-1) * c**(p-1)/(v_dt+c)**p (这里的p&c是浮点数和v_dt a~500长浮点数阵列) 在我的机器上,这个计算大约需要1/50秒 (使用timeit计时:1000个循环,每个循环的最佳时间为3:21.8毫秒) 问题是这个小函数(我还有其他几个类似的函数)在循环中每次迭代调用500次,循环的运行次数在100次左右。所以这一小行突然给我的运行时间增加了20分钟 在pyth

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

(p-1) * c**(p-1)/(v_dt+c)**p
(这里的p&c是浮点数和v_dt a~500长浮点数阵列)

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

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

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

在python中加速数学计算的最佳方法是什么?使用python技巧可以完成多少工作?我已经研究过c_类型,可能还有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
使用不同的
p
c

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 vintage的Centron笔记本电脑)

这不是那种
cython
或其他自己动手编译的代码可以做得更好的计算
numpy
已经过优化,可以有效地执行这样的数学运算


我认为你需要从大局出发。为什么需要经常打电话?使用较大的阵列是否可以减少调用次数

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

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
使用不同的
p
c

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 vintage的Centron笔记本电脑)

这不是那种
cython
或其他自己动手编译的代码可以做得更好的计算
numpy
已经过优化,可以有效地执行这样的数学运算

我认为你需要从大局出发。为什么需要经常打电话?使用较大的阵列是否可以减少调用次数

我觉得这是一件令人惊讶和有趣的事

快速总结:

  • 最有趣的是,对于小数组(我认为这是令人惊讶和有趣的

    快速总结:


    • 最有趣的是,对于小型阵列(我建议在深入到微观优化之前寻找宏观优化:你确定程序需要循环那么多次吗?嵌套循环是否每次都需要执行此计算?这些计算中的一些是否可以保存以供以后参考?也许可以在这里尝试@BJH记住,代码审查需要完整的工作代码,用于接受问题。此代码片段是
      示例代码
      ,可能不会被很好地接受。如果您在那里发布整个场景(包括用例),那么我们非常欢迎。:)求幂通常是昂贵的。而不是
      (p-1)*c**(p-1)/(v_dt+c)*p
      ,请查看是否
      (p-1)*(c/(v_dt+c))**p/c
      更快。如果您没有为该行代码提供任何上下文,则很难提出优化建议。这些参数中的哪些参数因调用而异?您可以预先计算该表达式的某些参数。您使用该结果做什么?据我们所知,可能有一些方法可以跳过对该中间数组的计算总之。我建议在深入到微观优化之前先寻找宏观优化:你确定程序需要循环那么多次吗?嵌套循环是否每次都需要执行此计算?这些计算中的一些是否可以保存以供以后参考?也许可以在这里尝试@BJH请记住,代码复查是需要完整的工作代码才能接受问题。此代码片段是
      示例代码
      ,可能不会被很好地接受。如果您在那里发布整个场景(包括用例),那么我们非常欢迎。:)求幂通常是昂贵的。而不是
      (p-1)*c**(p-1)/(v_dt+c)**p
      ,请查看是否
      (p-1)*(c/(v_dt+c))**p/c
      更快。如果您没有为该行代码提供任何上下文,则很难提出优化建议。这些参数中的哪些参数因调用而异?您可以预先计算该表达式的某些参数。您使用该结果做什么?据我们所知,可能有一些方法可以跳过对该中间数组的计算总共