Python:调用函数真的很慢?

时间:2013-02-10 03:06:47

标签: python function time call

我有一个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)

2 个答案:

答案 0 :(得分:1)

分析表明在分析期间调用clean方法大约需要28秒中的6秒。在此期间它也会被召唤370万次。

这意味着您显示的循环必须是软件的主循环。主循环也只做以下事情:

  1. 检查元素是否脏。
  2. 如果是,则绘制它。
  3. 然后清理它。
  4. 由于大多数元素都不脏(update()只被调用这些370万个循环中的11千个),最终的结果是你的主循环现在只做一件事:检查元素是否脏,然后调用.clean()就可以了。

    如果元素是脏的,只调用clean,就可以有效地将主循环切成两半。

      

    我是否真的必须小心不要完全滞后我的代码?

    是。如果你有一个非常紧凑的循环,在大多数时间什么都不做,那么你必须确保这个循环实际上是紧的。

      

    这非常令人不安。

    不,这是一个基本的计算事实。

答案 1 :(得分:0)

(评论,但我的统计数据是低到“评论”)

如果你正在调用370万次元素.getDirty() 它只脏了11000次, 你应该保持一个脏的清单,而不是每次都进行轮询。

也就是说,不要设置脏标志,而是将脏元素添加到脏元素列表中。 看起来您可能需要为每个图层添加一个脏列表。