我有一个Element
类,它有一些功能,如下所示:
def clean(self):
self.dirty = False
我有1024个元素,我在clean
循环中对每个元素调用while 1:
。
如果我停止调用clean
方法,则游戏帧速率从76fps上升到250 fps。
这非常令人不安。我是否真的必须小心不要完全滞后我的代码?
编辑(此处为完整代码) :
250 fps代码
for layer in self.layers:
elements = self.layers[layer]
for element in elements:
if element.getDirty():
element.update()
self.renderImage(element.getImage(), element.getRenderPos())
element.clean()
76fps代码
for layer in self.layers:
elements = self.layers[layer]
for element in elements:
if element.getDirty():
element.update()
self.renderImage(element.getImage(), element.getRenderPos())
element.clean()
2Edit(这是分析结果):
Sat Feb 9 22:39:58 2013 stats.dat
23060170 function calls (23049668 primitive calls) in 27.845 seconds
Ordered by: internal time
List reduced from 613 to 20 due to restriction <20>
ncalls tottime percall cumtime percall filename:lineno(function)
3720076 5.971 0.000 12.048 0.000 element.py:47(clean)
909 4.869 0.005 17.918 0.020 chipengine.py:30(updateElements)
3742947 4.094 0.000 5.443 0.000 copy.py:67(copy)
4101 3.972 0.001 3.972 0.001 engine.py:152(killScheduledElements)
11773 1.321 0.000 1.321 0.000 {method 'blit' of 'pygame.Surface' objects}
4 1.210 0.302 1.295 0.324 resourceloader.py:14(__init__)
3720076 0.918 0.000 0.918 0.000 element.py:55(getDirty)
1387 0.712 0.001 0.712 0.001 {built-in method flip}
3742947 0.705 0.000 0.705 0.000 copy.py:102(_copy_immutable)
3728284 0.683 0.000 0.683 0.000 {method 'copy' of 'pygame.Rect' objects}
3743140 0.645 0.000 0.645 0.000 {method 'get' of 'dict' objects}
5494 0.566 0.000 0.637 0.000 element.py:89(isBeclouded)
2296 0.291 0.000 0.291 0.000 {built-in method get}
1 0.267 0.267 0.267 0.267 {built-in method init}
1387 0.244 0.000 25.714 0.019 engine.py:67(updateElements)
2295 0.143 0.000 0.143 0.000 {method 'tick' of 'Clock' objects}
11764 0.095 0.000 0.169 0.000 element.py:30(update)
8214/17 0.062 0.000 4.455 0.262 engine.py:121(createElement)
40 0.052 0.001 0.052 0.001 {built-in method load_extended}
36656 0.046 0.000 0.067 0.000 element.py:117(isCollidingWith)
答案 0 :(得分:1)
分析表明在分析期间调用clean方法大约需要28秒中的6秒。在此期间它也会被召唤370万次。
这意味着您显示的循环必须是软件的主循环。主循环也只做以下事情:
由于大多数元素都不脏(update()只被调用这些370万个循环中的11千个),最终的结果是你的主循环现在只做一件事:检查元素是否脏,然后调用.clean()就可以了。
如果元素是脏的,只调用clean,就可以有效地将主循环切成两半。
我是否真的必须小心不要完全滞后我的代码?
是。如果你有一个非常紧凑的循环,在大多数时间什么都不做,那么你必须确保这个循环实际上是紧的。
这非常令人不安。
不,这是一个基本的计算事实。
答案 1 :(得分:0)
(评论,但我的统计数据是低到“评论”)
如果你正在调用370万次元素.getDirty() 它只脏了11000次, 你应该保持一个脏的清单,而不是每次都进行轮询。
也就是说,不要设置脏标志,而是将脏元素添加到脏元素列表中。 看起来您可能需要为每个图层添加一个脏列表。