1

次のElementようないくつかの関数を持つクラスがあります。

def clean(self):
    self.dirty = False

1024 個の要素があり、cleanそれぞれをwhile 1:ループで呼び出しています。

メソッドの呼び出しを停止するとclean、ゲームのフレームレートが 76 fps から 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()

2編集(プロファイリング結果はこちら):

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)
4

2 に答える 2

1

プロファイリングによると、clean メソッドの呼び出しには、プロファイリング中に 28 秒のうち約 6 秒かかります。その間、370 万回も呼び出されます。

つまり、表示しているループはソフトウェアのメイン ループでなければなりません。そのメイン ループは、次のことだけを行います。

  1. 要素が汚れているかどうかを確認します。
  2. ある場合は、それを描画します。
  3. その後、それをきれいにします。

ほとんどの要素はダーティではないため (update() は、これら 370 万回のループのうち 11,000 回しか呼び出されない)、最終的な結果として、メイン ループはただ 1 つのことを行うことになります: 要素がダーティかどうかを確認し、次に .clean( を呼び出します。 ) その上に。

要素が汚れている場合にのみ clean を呼び出すことで、メイン ループを効果的に半分に削減できます。

コードが完全に遅れないように、本当に注意する必要がありますか?

はい。ほとんどの場合何もしない非常にタイトなループがある場合は、このループが実際にタイトであることを確認する必要があります。

これはかなり気がかりです。

いいえ、それは基本的なコンピューティングの事実です。

于 2013-02-10T03:51:42.923 に答える
0

(コメント、しかし私の統計は「コメント」するには低すぎる)

element.getDirty() を 370 万回呼び出していて、ダーティが 11,000 回しかない場合は、毎回ポーリングするのではなく、ダーティ リストを保持する必要があります。

つまり、ダーティ フラグを設定せずに、ダーティ エレメントをダーティ エレメント リストに追加します。レイヤーごとにダーティ リストが必要なようです。

于 2013-02-10T07:45:39.170 に答える