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