在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?

在Mono 2.6(.Net 3.5)中,将List of items从树的父项传递到其叶子的GC最有效的方法是什么?

您没有确切说明什么类型的对象会占用所有内存,但从您提到ToList()的情况来看,听起来您正在创建许多List实例,以及LINQ中可能的中间对象。

为了减少GC的压力,您需要减少分配的数量。不应在每个Filter()中分配新的List实例。也许您甚至不应该使用List,而是使用其他一些O(1)的数据结构来删除。或者,不要从列表中删除元素,而只是用一些占位符替换应该删除的元素(null可能会这样做)。

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

public void Filter(Target target)

这样,就没有必要分配任何东西。而且,您将多次调用MoveNext()Current与多次调用Filter()进行交易,因此忽略GC时的性能可能也不会受到影响。(虽然可以,MoveNext()Current可以内联,但对Filter()的递归调用不能。)