在Mono 2.6(.Net 3.5)中,将List of items从树的父项传递到其叶子的GC最有效的方法是什么?
本文关键字:叶子 是什么 方法 有效 GC Net Mono of items List | 更新日期: 2023-09-27 18:00:00
所以我们有一个基于类的树(伪代码):
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?
您没有确切说明什么类型的对象会占用所有内存,但从您提到ToList()的情况来看,听起来您正在创建许多List实例,以及LINQ中可能的中间对象。
为了减少GC的压力,您需要减少分配的数量。不应在每个Filter()中分配新的List实例。也许您甚至不应该使用List,而是使用其他一些O(1)的数据结构来删除。或者,不要从列表中删除元素,而只是用一些占位符替换应该删除的元素(null可能会这样做)。
您可能需要考虑分别处理每个目标:
public void Filter(Target target)
这样,就没有必要分配任何东西。而且,您将多次调用MoveNext()
和Current
与多次调用Filter()
进行交易,因此忽略GC时的性能可能也不会受到影响。(虽然可以,MoveNext()
和Current
可以内联,但对Filter()
的递归调用不能。)