我正在学习Python,看到了一个我之前见过的模型的仿真示例。其中一个函数看起来不必要地冗长,所以我认为尝试让它更有效率是个好练习。我的尝试虽然需要更少的代码,但速度大约是原函数的1/60。是的,我把它搞糟了60倍。
我的问题是,我哪里错了?我已经尝试计时函数的各个部分,但没有看出瓶颈在哪里。
这是原始函数。它是用于模拟人们生活在网格上的模型,并且他们的幸福感取决于他们是否与大多数邻居相同种族(这是谢林隔离模型)。因此,我们为每个人提供一个x,y坐标,并通过检查每个邻居的种族来确定他们的幸福感。
(The rest of the code that creates the class is 在该网站上,这里是示例代码的来源。)
(以下是时序结果:)
我希望有Python知识的人能立即看出我的错误,而不必深入了解其余代码的细节。你能看出为什么我的代码比原始代码差那么多吗?
我的问题是,我哪里错了?我已经尝试计时函数的各个部分,但没有看出瓶颈在哪里。
这是原始函数。它是用于模拟人们生活在网格上的模型,并且他们的幸福感取决于他们是否与大多数邻居相同种族(这是谢林隔离模型)。因此,我们为每个人提供一个x,y坐标,并通过检查每个邻居的种族来确定他们的幸福感。
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
这是我的代码,正如我所说的那样,速度非常慢。我想通过创建一个“偏移量”列表来避免在上面编写所有的if语句,以便将其添加到每个人的坐标中,以确定可能邻居的位置,检查是否为有效位置,然后检查邻居的种族。
def is_unhappy2(self, x, y):
thisRace = self.agents[(x,y)]
count_same = 0
count_other = 0
for xo, yo in list(itertools.product([-1,0,1],[-1,0,1])):
if xo==0 and yo==0:
# do nothing for case of no offset
next
else:
# check if there's a neighbor at the offset of (xo, yo)
neighbor = tuple(np.add( (x,y), (xo,yo) ))
if neighbor in self.agents.keys():
if self.agents[neighbor] == thisRace:
count_same += 1
else:
count_other += 1
if count_same+count_other == 0:
return False
else:
return float(count_same) / (count_same + count_other) < self.similarity threshold
(The rest of the code that creates the class is 在该网站上,这里是示例代码的来源。)
(以下是时序结果:)
%timeit s.is_unhappy2(49,42)
100 loops, best of 3: 5.99 ms per loop
%timeit s.is_unhappy(49,42)
10000 loops, best of 3: 103 µs per loop
我希望有Python知识的人能立即看出我的错误,而不必深入了解其余代码的细节。你能看出为什么我的代码比原始代码差那么多吗?