c# – 具有非常快速的迭代和良好的添加和移除速度的集合

我正在追踪一个可以快速迭代的集合.我也会定期添加项目和删除(特定)项目,因此理想情况下这些操作也会很快.

我正在开发xbox,因此仅限于紧凑的框架(或多或少).将垃圾和对象分配保持在最低限度非常重要,因此我可以为我的对象预先分配空间的任何事情都会很棒.

我将在集合中存储uints(但如果需要可以是int).一般的解决方案会很好,因为我相信我将来会有需求.

一个.net集合将是理想的,没有一个轻量级和开源的东西会很棒.

是否有适合我需求的收藏课程?如果没有,我将如何创建一个?

为了详细说明,它们是对象id,类应该处理每个帧.它们通常按升序添加,有间隙.没有上限.任何可以删除,这将留下空白.
迭代顺序并不完全重要,但如果顺序一致,它将非常有用(特别是对于调试).

解决方法:

我有两个建议尝试:

首先,如何使用Reflector或ILSpy查看Generic List< T>?我假设实现不在CF中,或者您可以使用它.通用列表< T>是数组支持并使用从长度为4的数组开始的加倍算法,每次调用.Add都会导致它加倍并将Array.Copy执行到新数组中.除非您明确将Capacity设置为零,否则不会调整大小,因此请从内存的角度提防.添加是一回事,但每次删除都会导致在删除索引后复制和左移数组.

第二个建议就是这个 – 关于创建一个包装整数数组来处理它的自定义类,它使用类似的双算法(或四倍)到Generic List< T>. (以处理调整大小)但是从大小256开始.您可以根据需要随意添加对象整数id,并且它不会经常加倍.您还可以通过将(int)-1或uint.MaxValue指定为“空索引”来模拟删除,这意味着删除时不会出现Array.Copy.然后,每帧应用某种快速排序以在绘制之前对对象索引数组进行排序.如果按升序排序,所有-1将出现在开头(或结尾处的uint.MaxValues),可以忽略.您可以通过调整大小并在单独的线程上删除前面的-1来定期“收集”索引数组(注意 – 使用锁定;)

你怎么看?只是认为你将每帧一次计算一次计算以进行快速排序(对于每个删除和一些添加(昂贵)的xbox与内存分配/收集并不昂贵).

UPDATE – BlockArray – List< T []>其中T是固定大小的数组

对此进一步评论.我最近试验了动态大小的列表的最有效的数据结构,并通过实验发现了数组块 – 一个由List of T []支持的类,其中每个T []是一个固定大小的块数组,例如: 512,4096,8192与普通List< T>相比具有几个优点.

我发现List< T []>中的Add()(其中大小未知)的实现.列表< T>的广告优于Add(),特别是当总尺寸变大时.这是由于List< T>的倍增算法,它要求新的数组大小为旧的2x,而memcpy是超过大小时的旧数组.

迭代速度类似.预分配(预定义容量)比List< T>慢得多.对于小块大小(512),但对于大块大小(8192)仅略慢.删除是有问题的,因为需要复制/左移多个块.

有趣的是List< T []> (阻止列表),您可以缓存/池化块.如果足够小,T []的块适合小对象堆(有利于压缩,更快的分配),可能适合L2缓存并且可以预先分配和汇集多个块

上一篇:使用C#和Visual Studio进行Xbox应用程序开发


下一篇:vue拖放组件dnd-grid,容器与box间数据传递和渲染的代码逻辑