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 实例。也许您甚至不应该使用 List,而是使用其他一些 O(1) 的数据结构进行删除。或者,不要从列表中删除元素,而只是用一些占位符替换应该删除的元素(null 可能会这样做)。

于 2013-02-17T11:39:00.663 回答
0

您可能需要考虑分别处理每个目标:

public void Filter(Target target)

这样,就不需要分配任何东西。而且您正在多次调用MoveNext()Current多次调用Filter(),因此忽略 GC 时的性能也可能不会受到影响。(虽然它可以MoveNext()并且Current可以内联,但递归调用Filter()can't。)

于 2013-02-17T11:39:31.023 回答