所以我们有一个基于类的树,就像这样(伪代码):
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兆的垃圾。
我们调用每个帧的函数,这是我们无法避免的。我们真的不想调用每个帧/每个N帧的GC.collect。
我们传递给子集合的列表是通过LINQ表达式生成的,末尾带有.ToList() (传递过滤出的IEnumerator (意味着链接到原始集合的部分)会使性能下降更低)。
在我们的Filter函数中,我们不修改给定的集合--只是过滤它。
所以我的问题是:如何保持至少相同的过滤性能,并摆脱GC丢失我们的fps?
发布于 2013-02-17 19:39:01
您没有确切地说哪种类型的对象占用了所有的内存,但是从您提到的ToList()看起来您正在创建大量的List实例,以及可能的LINQ内部的中间对象。
为了减少GC压力,您需要减少分配量。您不应该在每个Filter()中分配新的列表实例。也许您甚至不应该使用List,而应该使用O(1)表示删除的其他数据结构。或者,不要从列表中删除元素,而是将应该删除的元素替换为某个占位符(null也可以)。
发布于 2013-02-17 19:39:31
您可能需要考虑分别处理每个目标:
public void Filter(Target target)这样,就不需要分配任何东西了。而且你需要多次调用MoveNext()和Current,而调用Filter()的次数很多,所以忽略GC时的性能也不会受到影响。(虽然它可以,但MoveNext()和Current可以内联,但对Filter()的递归调用不能。)
https://stackoverflow.com/questions/14920555
复制相似问题