0

したがって、次のようなクラスに基づくツリーがあります (疑似コード):

class TreeItem {
    private TreeItem parent;
    private List<TreeItem> leaves;
   public void Filter(List<Target> targets) { /* filter given list and pass to all leaves */ }
}

そして、これは GC を文字通り泣かせます - それは時折落ち込み、FPS は 15 まで下がり、約 2.5 メガのゴミをフィルタリングします。

その関数をフレームごとに呼び出しますが、これは避けられないことです。GC.collect各フレーム/各フレームを呼び出したくありませんN

子に渡すリストは、最後に LINQ 式を介して生成.ToList()されます (フィルター処理された IEnumerator (元のコレクションの一部へのリンクを意味します) を渡すと、パフォーマンスがさらに低下します)。

このFilter関数では、特定のコレクションを変更しません。フィルターするだけです。

だから私の質問は: 少なくとも同じフィルタリング パフォーマンスを維持し、GC が fps を落とすのを取り除く方法は?

4

2 に答える 2

0

どのタイプのオブジェクトがそのすべてのメモリを占有するかは正確にはわかりませんが、ToList() についての言及から、多くの List インスタンスと、LINQ 内の可能な中間オブジェクトを作成しているように聞こえます。

GC の負荷を軽減するには、割り当ての量を減らす必要があります。各 Filter() に新しい List インスタンスを割り当てないでください。おそらく、リストを使用するべきではありませんが、削除するために O(1) である他のデータ構造を使用する必要があります。または、リストから要素を削除せず、削除する必要がある要素をプレースホルダーに置き換えます (null の場合もあります)。

于 2013-02-17T11:39:00.663 に答える
0

各ターゲットを個別に処理することを検討してください。

public void Filter(Target target)

そうすれば、何も割り当てる必要はありません。そして、何度も呼び出して何度も呼び出してMoveNext()いるので、GC を無視した場合のパフォーマンスも影響を受けない可能性があります。(それはできますし、インライン化することもできますが、再帰呼び出しはできません。)CurrentFilter()MoveNext()CurrentFilter()

于 2013-02-17T11:39:31.023 に答える