Python中的操作顺序和快速计算

时间:2014-03-07 14:26:52

标签: python performance optimization

我正在尝试优化Python代码,其中必须多次(多次)评估以下数学函数

from math import pow, pi
from scipy.special import gamma

def norm_spirals(a,k):
    return pi*pow(abs(gamma(0.25+0.5*k+0.5j*a)/gamma(0.75+0.5*k+0.5j*a)),2)

我已使用cProfiletimeit尽可能优化了我的代码。我还删除了程序的call,并直接在代码中嵌入了这个计算。我能想到的优化的最后一步是调整数学运算的顺序以加速评估。上面的公式是我使用timeit获得的最快的表格。

  • 你会想到这个公式的另一个计算顺序可能会更快吗?
  • 您对我可以使用的其他优化有任何想法吗?

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

这里有四个简单的转换来加速你的代码:

1)将pow(x, 2)替换为x ** 2.0

def norm_spirals(a,k):
    return pi* abs(gamma(0.25+0.5*k+0.5j*a)/gamma(0.75+0.5*k+0.5j*a)) ** 2.0

2)将common subexpression0.25+0.5*k+0.5j*a

分解出来
def norm_spirals(a,k):
    se = 0.25 + 0.5*k + 0.5j*a
    return pi * abs(gamma(se)/gamma(se + 0.5)) ** 2.0

3)本地化全局查找:

def norm_spirals(a,k, pi=pi, abs=abs, gamma=gamma):
    se = 0.25 +0.5*k + 0.5j*a
    return pi * abs(gamma(se)/gamma(se + 0.5)) ** 2.0

4)用b * b替换方形操作。这称为strength reduction

def norm_spirals(a,k, pi=pi, abs=abs, gamma=gamma):
    se = 0.25 + 0.5*k + 0.5j * a
    b = abs(gamma(se)/gamma(se + 0.5))
    return b * b * pi

答案 1 :(得分:0)

通过引入temp var并删除对pow的调用,我得到它快15%(python 2.7):

def norm_spirals(a, k):
    _ = 0.5 * k + 0.5j * a
    return pi * abs(gamma(0.25 + _) / gamma(0.75 + _)) ** 2

对于python 3,增益仅为11%。

声明:
我没有安装scipy所以对于我使用的伽玛

def gamma(a):
    return a

所以“快了15%”可能会有点误导。

答案 2 :(得分:0)

如果使用相同的参数多次调用norm_spirals(),那么您可以尝试memoization来缓存结果,看看它是否有所作为。