Python 为什么我的(新手)代码这么慢?
我正在学习python,遇到了一个我以前见过的模型的模拟。其中一个函数看起来太长了,所以我认为提高它的效率是一种很好的做法。我的尝试虽然需要更少的代码,但速度大约是它的60分之一。是的,我让情况恶化了60倍 我的问题是,我哪里做错了?我尝试了对函数的各个部分进行计时,但没有看到瓶颈在哪里 这是原始函数。这是一个模型,人们生活在一个网格上,他们的幸福取决于他们是否与大多数邻居是同一种族。(这是谢林的。)所以我们给一个人一个x,y坐标,然后通过检查每个邻居的种族来确定他们的幸福感Python 为什么我的(新手)代码这么慢?,python,performance,profiler,Python,Performance,Profiler,我正在学习python,遇到了一个我以前见过的模型的模拟。其中一个函数看起来太长了,所以我认为提高它的效率是一种很好的做法。我的尝试虽然需要更少的代码,但速度大约是它的60分之一。是的,我让情况恶化了60倍 我的问题是,我哪里做错了?我尝试了对函数的各个部分进行计时,但没有看到瓶颈在哪里 这是原始函数。这是一个模型,人们生活在一个网格上,他们的幸福取决于他们是否与大多数邻居是同一种族。(这是谢林的。)所以我们给一个人一个x,y坐标,然后通过检查每个邻居的种族来确定他们的幸福感 def is_un
def is_unhappy(self, x, y):
race = self.agents[(x,y)]
count_similar = 0
count_different = 0
if x > 0 and y > 0 and (x-1, y-1) not in self.empty_houses:
if self.agents[(x-1, y-1)] == race:
count_similar += 1
else:
count_different += 1
if y > 0 and (x,y-1) not in self.empty_houses:
if self.agents[(x,y-1)] == race:
count_similar += 1
else:
count_different += 1
if x < (self.width-1) and y > 0 and (x+1,y-1) not in self.empty_houses:
if self.agents[(x+1,y-1)] == race:
count_similar += 1
else:
count_different += 1
if x > 0 and (x-1,y) not in self.empty_houses:
if self.agents[(x-1,y)] == race:
count_similar += 1
else:
count_different += 1
if x < (self.width-1) and (x+1,y) not in self.empty_houses:
if self.agents[(x+1,y)] == race:
count_similar += 1
else:
count_different += 1
if x > 0 and y < (self.height-1) and (x-1,y+1) not in self.empty_houses:
if self.agents[(x-1,y+1)] == race:
count_similar += 1
else:
count_different += 1
if x > 0 and y < (self.height-1) and (x,y+1) not in self.empty_houses:
if self.agents[(x,y+1)] == race:
count_similar += 1
else:
count_different += 1
if x < (self.width-1) and y < (self.height-1) and (x+1,y+1) not in self.empty_houses:
if self.agents[(x+1,y+1)] == race:
count_similar += 1
else:
count_different += 1
if (count_similar+count_different) == 0:
return False
else:
return float(count_similar)/(count_similar+count_different) < self.similarity_threshold
我希望有python知识的人能够立即看到我做错了什么,而不必深入了解其余代码的细节。你能理解为什么我的代码比原来的代码糟糕得多吗?罪魁祸首似乎是这一行:
neighbor = tuple(np.add( (x,y), (xo,yo) ))
将其更改为此将显示巨大的加速:
neighbor = (x + xo, y + yo)
不要使用
np。添加,只使用邻居=(x+xo,y+yo)
。这将使它更快(在我的小测试中快10倍)
你也可以
- 询问self.agents中的邻居:
而不使用.keys()
省略列表
选中xo或yo
,并且没有空的if块
避免在自代理中重复查找邻居
结果:
for xo, yo in itertools.product([-1,0,1],[-1,0,1]):
if xo or yo:
neighbor = self.agents.get((x+xo, y+yo))
if neighbor is not None:
if neighbor == thisRace:
count_same += 1
else:
count_other += 1
你可以加上
self.neighbor_deltas = tuple(set(itertools.product([-1,0,1],[-1,0,1])) - {(0, 0)})
到类初始值设定项,然后您的函数可以只使用这些预先计算的增量:
for xo, yo in self.neighbor_deltas:
neighbor = self.agents.get((x+xo, y+yo))
if neighbor is not None:
if neighbor == thisRace:
count_same += 1
else:
count_other += 1
恭喜你决定改进这位作者荒谬重复的代码,顺便说一句。你的代码慢吗?每循环5.99毫秒时的100个循环总计599毫秒,103微秒时的10000个循环总计1030毫秒。也许我被计时结果弄糊涂了?@ryan重要的是每个循环的时间,而不是运行基准测试所花费的总时间。迭代次数只是给你一个置信区间的概念。@TylerH有9次向上投票,到目前为止没有接近投票,这似乎是一个可以接受的堆栈溢出问题。有些问题可以在这两个网站上讨论。这也不是一个很好的代码审查问题,因为它包含了一点关于理解其他代码的内容。在别的地方谈论话题并不能使它偏离话题。@TylerH@RubberDuck说它属于其他地方并不是一个很接近的理由。不幸的是,即使根据新的信息,我们也不能改变我们的简历理由,所以我不能这样做。
self.neighbor_deltas = tuple(set(itertools.product([-1,0,1],[-1,0,1])) - {(0, 0)})
for xo, yo in self.neighbor_deltas:
neighbor = self.agents.get((x+xo, y+yo))
if neighbor is not None:
if neighbor == thisRace:
count_same += 1
else:
count_other += 1