Python 减少函数调用
我分析了我的python程序,发现下面的函数运行时间太长。也许,我可以使用不同的算法,让它运行得更快。然而,我已经读到,我也可以通过减少函数调用来提高速度,特别是当它在循环中被重复调用时。我是一个python新手,我想学习如何做到这一点,看看它能快多少。目前,该功能是:Python 减少函数调用,python,performance,Python,Performance,我分析了我的python程序,发现下面的函数运行时间太长。也许,我可以使用不同的算法,让它运行得更快。然而,我已经读到,我也可以通过减少函数调用来提高速度,特别是当它在循环中被重复调用时。我是一个python新手,我想学习如何做到这一点,看看它能快多少。目前,该功能是: def potentialActualBuyers(setOfPeople,theCar,price): count=0 for person in setOfPeople: if person.getUtilit
def potentialActualBuyers(setOfPeople,theCar,price):
count=0
for person in setOfPeople:
if person.getUtility(theCar) >= price and person.periodCarPurchased==None:
count += 1
return count
其中setOfPeople
是person
对象的列表。我尝试了以下方法:
def potentialActualBuyers(setOfPeople,theCar,price):
count=0
Utility=person.getUtility
for person in setOfPeople:
if Utility(theCar) >= price and person.periodCarPurchased==None:
count += 1
return count
然而,这给了我一个错误,在赋值之前引用了局部变量“person”
任何建议,如何减少函数调用或任何其他可以使代码更快的更改
同样,我是python新手,尽管我可能会使用更好的算法,但学习上述问题的答案仍然是值得的
非常感谢
*****编辑*****
添加getUtility
方法:
def getUtility(self,theCar):
if theCar in self.utility.keys():
return self.utility[theCar]
else:
self.utility[theCar]=self.A*(math.pow(theCar.mpg,self.alpha))*(math.pow(theCar.hp,self.beta))*(math.pow(theCar.pc,self.gamma))
返回自我效用[theCar]
*****编辑:寻求新的想法*****
有没有办法进一步加快速度。我用亚历克斯建议的方法把时间缩短了一半。我可以加快速度吗?
谢谢。试试看(假设所有人都是同一类型的人
):
此外,使用is None
而不是==None
应该稍微快一点。如果交换和
术语有帮助,请尝试。试一下(假设所有人都是同一类型的人
):
此外,使用
is None
而不是==None
应该稍微快一点。如果交换和术语有帮助,请尝试。方法只是绑定到对象的函数:
Utility = Person.getUtility
for person in setOfPeople:
if Utility(person, theCar) ...
但这并没有消除函数调用,而是消除了属性查找。方法只是绑定到对象的函数:
Utility = Person.getUtility
for person in setOfPeople:
if Utility(person, theCar) ...
不过,这并没有消除函数调用,而是消除了属性查找。我怀疑,在这种情况下,通过提升对person.getUtility的查找(按类,而不是按实例,正如其他实例所指出的那样),可以获得更高的速度。也许…:
return sum(1 for p in setOfPeople
if p.periodCarPurchased is None
and p.getUtility(theCar) >= price)
但我怀疑大部分时间实际上都花在执行getUtility
(可能在查找p.periodCarPurchased
时,如果这是一个与普通旧属性相反的奇特属性——我将后者移到了和
之前,以防它是一个普通属性,并且可以保存大量的getUtility
调用)。您的分析表明,与所讨论的方法(以及可能的属性)相比,在这个函数中花费的时间(扣除对其他函数的调用)占了多少?我怀疑,在这种情况下,通过提升对person.getUtility的查找,您可以获得多大的加速(按类,而不是按实例,正如其他实例所指出的那样).也许…:
return sum(1 for p in setOfPeople
if p.periodCarPurchased is None
and p.getUtility(theCar) >= price)
但我怀疑大部分时间实际上都花在执行getUtility
(可能在查找p.periodCarPurchased
时,如果这是一个与普通旧属性相反的奇特属性——我将后者移到了和
之前,以防它是一个普通属性,并且可以保存大量的getUtility
调用)。您的分析表明,与所讨论的方法(以及可能的属性)相比,花在这个函数上的时间(扣除对其他函数的调用)占了多少?这一行让我的眼睛流血了:
self.utility[theCar]=self.A*(math.pow(theCar.mpg,self.alpha))*(math.pow(theCar.hp,self.beta))*(math.pow(theCar.pc,self.gamma))
让我们让它变得清晰易懂,然后看看它是否能更快。首先是一些空格:
self.utility[theCar] = self.A * (math.pow(theCar.mpg, self.alpha)) * (math.pow(theCar.hp, self.beta)) * (math.pow(theCar.pc, self.gamma))
现在我们可以看到有很多多余的括号;请删除它们:
self.utility[theCar] = self.A * math.pow(theCar.mpg, self.alpha) * math.pow(theCar.hp, self.beta) * math.pow(theCar.pc, self.gamma)
Hmmm:3次查找math.pow
和3次函数调用。幂有三种选择:x**y
,内置的pow(x,y[,z])
,和math.pow(x,y)
。除非你有充分的理由使用其中一种,否则它是最好的(IMHO)要选择x**y
,请保存属性查找和函数调用
self.utility[theCar] = self.A * theCar.mpg ** self.alpha * theCar.hp ** self.beta * theCar.pc ** self.gamma
annnnnnd在这里,让我们去掉水平滚动条:
self.utility[theCar] = (self.A
* theCar.mpg ** self.alpha
* theCar.hp ** self.beta
* theCar.pc ** self.gamma)
一种可能需要对现有代码进行大量重写,而且可能不会有任何帮助(在Python中),那就是通过到处记录日志并使用log\u utility=log\u A+log\u mpg*alpha…
这一行让我的眼睛流血:
self.utility[theCar]=self.A*(math.pow(theCar.mpg,self.alpha))*(math.pow(theCar.hp,self.beta))*(math.pow(theCar.pc,self.gamma))
让我们让它变得清晰易懂,然后看看它是否能更快。首先是一些空格:
self.utility[theCar] = self.A * (math.pow(theCar.mpg, self.alpha)) * (math.pow(theCar.hp, self.beta)) * (math.pow(theCar.pc, self.gamma))
现在我们可以看到有很多多余的括号;请删除它们:
self.utility[theCar] = self.A * math.pow(theCar.mpg, self.alpha) * math.pow(theCar.hp, self.beta) * math.pow(theCar.pc, self.gamma)
Hmmm:3次查找math.pow
和3次函数调用。幂有三种选择:x**y
,内置的pow(x,y[,z])
,和math.pow(x,y)
。除非你有充分的理由使用其中一种,否则它是最好的(IMHO)要选择x**y
,请保存属性查找和函数调用
self.utility[theCar] = self.A * theCar.mpg ** self.alpha * theCar.hp ** self.beta * theCar.pc ** self.gamma
annnnnnd在这里,让我们去掉水平滚动条:
self.utility[theCar] = (self.A
* theCar.mpg ** self.alpha
* theCar.hp ** self.beta
* theCar.pc ** self.gamma)
可能需要对现有代码进行大量重写,但可能不会有任何帮助(在Python中)这将是为了避免大部分的功耗计算,方法是在所有地方都使用日志,并使用log\u utility=log\u A+log\u mpg*alpha…
该错误指的是在枚举器中分配person之前引用person。它应该在“for person in set of people:”之后另外,当你说它需要很长时间才能运行时,你如何量化它?它实际需要多长时间,你正在运行的集合有多大?过早的优化是所有问题的根源。预计算方法引用不太可能为你带来任何加速。查看getUtility
内部可能会得出一些见解。你能我也怀疑getUtility
的实际逻辑会超过函数调用的开销。在做任何不自然的事情之前,先看看中有哪些选项