为什么使用Python3将canvas小部件导入Tkinter的速度很慢?
我刚刚开始在Python(3.2)中使用Tkinter模块,所以我决定用这个模块重写我的旧程序(我使用了curses模块)。 该程序是一个模拟器。 我实现的算法在没有用户界面的情况下运行得很快。这是我的程序(这是一个快速的实验,我从未使用过canvas小部件): 我没有报告gol,但问题不在该模块中。 问题是程序非常慢,我认为我不能很好地使用画布 编辑:这是gol模块,但我认为这不是问题所在为什么使用Python3将canvas小部件导入Tkinter的速度很慢?,python,performance,canvas,tkinter,conways-game-of-life,Python,Performance,Canvas,Tkinter,Conways Game Of Life,我刚刚开始在Python(3.2)中使用Tkinter模块,所以我决定用这个模块重写我的旧程序(我使用了curses模块)。 该程序是一个模拟器。 我实现的算法在没有用户界面的情况下运行得很快。这是我的程序(这是一个快速的实验,我从未使用过canvas小部件): 我没有报告gol,但问题不在该模块中。 问题是程序非常慢,我认为我不能很好地使用画布 编辑:这是gol模块,但我认为这不是问题所在 #!/usr/bin/python3 class World: def __init__(se
#!/usr/bin/python3
class World:
def __init__(self, width, height):
self.width, self.height = width, height
self.cells = [[False for row in range(self.height)] for column in range(self.width)]
def neighbours(self, x, y):
counter = 0
for i in range(-1, 2):
for j in range(-1, 2):
if ((0 <= x + i < self.width) and (0 <= y + j < self.height) and not (i == 0 and j == 0)):
if self.cells[x + i][y + j]:
counter += 1
return counter
def evolve(self):
cells_tmp = [[False for row in range(self.height)] for column in range(self.width)]
for x in range(self.width):
for y in range(self.height):
if self.cells[x][y]:
if self.neighbours(x, y) == 2 or self.neighbours(x, y) == 3:
cells_tmp[x][y] = True
else:
if self.neighbours(x, y) == 3:
cells_tmp[x][y] = True
self.cells = cells_tmp
#/usr/bin/python3
阶级世界:
定义初始值(自身、宽度、高度):
self.width,self.height=宽度,高度
self.cells=[[False表示范围内的行(self.height)]表示范围内的列(self.width)]
def邻居(自身、x、y):
计数器=0
对于范围(-1,2)内的i:
对于范围(-1,2)内的j:
如果((0我的猜测是,这是因为每次重新绘制电路板时,您都要创建一个包含900个对象的新网格。当您创建成千上万个对象时,画布会出现性能问题。因为每次迭代都要绘制900个对象,这将很快增加很多对象
我的建议是重构代码,绘制一次30x30正方形的网格,然后在每次迭代中只需更改每个网格元素的颜色。这应该足以让您快速循环生成。我猜,这是因为每次重新绘制电路板时,您都要创建一个包含900个对象的新网格众所周知,当您创建成千上万个对象时,会出现性能问题。由于每次迭代都要绘制900个对象,因此很快就会生成很多对象
我的建议是重构您的代码以绘制一次30x30正方形的网格,然后在每次迭代中只需更改每个网格元素的颜色。这应该足以让您非常快速地循环各代。以下是您的配置文件的一部分:
ncalls tottime percall cumtime percall filename:lineno(function)
125112 1.499 0.000 1.499 0.000 {method 'call' of 'tkapp' objects}
125100 1.118 0.000 6.006 0.000 /usr/lib/python3.2/tkinter/__init__.py:2190(_create)
125109 0.942 0.000 1.749 0.000 /usr/lib/python3.2/tkinter/__init__.py:69(_cnfmerge)
125106 0.906 0.000 3.065 0.000 /usr/lib/python3.2/tkinter/__init__.py:1059(_options)
125599 0.851 0.000 0.851 0.000 main.py:10(neighbours)
500433 0.688 0.000 0.688 0.000 {built-in method isinstance}
125100 0.460 0.000 6.787 0.000 main.py:64(draw)
250210 0.341 0.000 0.341 0.000 {method 'update' of 'dict' objects}
125100 0.321 0.000 6.327 0.000 /usr/lib/python3.2/tkinter/__init__.py:2219(create_rectangle)
250205 0.319 0.000 0.319 0.000 {built-in method _flatten}
139 0.255 0.002 8.093 0.058 main.py:63(play)
139 0.181 0.001 1.051 0.008 main.py:19(evolve)
125109 0.134 0.000 0.134 0.000 {method 'items' of 'dict' objects}
125108 0.107 0.000 0.107 0.000 {built-in method callable}
1 0.056 0.056 0.056 0.056 {built-in method create}
让我们在此提取您感兴趣的内容:
cumtime filename:lineno(function)
0.851 main.py:10(neighbours)
6.787 main.py:64(draw)
8.093 main.py:63(play)
1.051 main.py:19(evolve)
你大部分时间都花在draw
,包含在类应用程序的方法play
中
台词:
ncalls tottime percall cumtime percall filename:lineno(function)
125100 1.118 0.000 6.006 0.000 /usr/lib/python3.2/tkinter/__init__.py:2190(_create)
125106 0.906 0.000 3.065 0.000 /usr/lib/python3.2/tkinter/__init__.py:1059(_options)
表明你的团队确实在花时间创建矩形
因此,如果您想获得更好的性能,只需停止实例化内容。只需更新它们!顺便说一句,如果您使用矩阵而不是双循环,那么对draw
的调用将少得多。draw
速度很慢(6.787 cum.秒),但请记住,在这些循环中您也会浪费近1.5秒的时间
顺便说一句,gol.py
中的evolve
也可以通过删除这些双循环来大大改进。我认为您也可以对算法进行一些改进
编辑:
哦,gol
模块有助于解决“问题”的第十个方面:这是您个人资料的一部分:
ncalls tottime percall cumtime percall filename:lineno(function)
125112 1.499 0.000 1.499 0.000 {method 'call' of 'tkapp' objects}
125100 1.118 0.000 6.006 0.000 /usr/lib/python3.2/tkinter/__init__.py:2190(_create)
125109 0.942 0.000 1.749 0.000 /usr/lib/python3.2/tkinter/__init__.py:69(_cnfmerge)
125106 0.906 0.000 3.065 0.000 /usr/lib/python3.2/tkinter/__init__.py:1059(_options)
125599 0.851 0.000 0.851 0.000 main.py:10(neighbours)
500433 0.688 0.000 0.688 0.000 {built-in method isinstance}
125100 0.460 0.000 6.787 0.000 main.py:64(draw)
250210 0.341 0.000 0.341 0.000 {method 'update' of 'dict' objects}
125100 0.321 0.000 6.327 0.000 /usr/lib/python3.2/tkinter/__init__.py:2219(create_rectangle)
250205 0.319 0.000 0.319 0.000 {built-in method _flatten}
139 0.255 0.002 8.093 0.058 main.py:63(play)
139 0.181 0.001 1.051 0.008 main.py:19(evolve)
125109 0.134 0.000 0.134 0.000 {method 'items' of 'dict' objects}
125108 0.107 0.000 0.107 0.000 {built-in method callable}
1 0.056 0.056 0.056 0.056 {built-in method create}
让我们在此提取您感兴趣的内容:
cumtime filename:lineno(function)
0.851 main.py:10(neighbours)
6.787 main.py:64(draw)
8.093 main.py:63(play)
1.051 main.py:19(evolve)
你大部分时间都花在draw
,包含在类应用程序的方法play
中
台词:
ncalls tottime percall cumtime percall filename:lineno(function)
125100 1.118 0.000 6.006 0.000 /usr/lib/python3.2/tkinter/__init__.py:2190(_create)
125106 0.906 0.000 3.065 0.000 /usr/lib/python3.2/tkinter/__init__.py:1059(_options)
表明你的团队确实在花时间创建矩形
因此,如果您想获得更好的性能,只需停止实例化内容。只需更新它们!顺便说一句,如果您使用矩阵而不是双循环,那么对draw
的调用将少得多。draw
速度很慢(6.787 cum.秒),但请记住,在这些循环中您也会浪费近1.5秒的时间
顺便说一句,gol.py
中的evolve
也可以通过删除这些双循环来大大改进。我认为您也可以对算法进行一些改进
编辑:
哦,gol
模块在“问题”的第十个方面起到了作用:什么是进化
做什么?进化()根据生命规则的游戏改变矩阵。进化
做什么?进化()根据生命规则的游戏改变矩阵。