【问题标题】:Good way to manage very large collection管理大量收藏的好方法
【发布时间】:2015-05-08 17:57:42
【问题描述】:

我试图想出一种快速有效的方法来处理大量相同的结构类型的项目,其中数组可以随着时间的推移而增长,并在条件合适时快速并有选择地删除项目。

应用程序将以相对较快的速度传入大量数据,我需要快速分析它,更新一些 UI 信息,并删除旧数据点以为新数据点腾出空间。与其他数据相比,我需要更长时间地保留某些感兴趣的数据点。

数据负载包含 2 个整数,代表物理频谱数据:频率、功率等。“老化”只是一些元数据,我将使用这些元数据来确定何时是淘汰旧的好时机数据。

我认为使用 LinkedList 将是一个不错的选择,因为它可以轻松地从集合中间删除项目,但我需要能够执行以下伪代码:

for(int i = 0; i < myCollection.Length; i++)
{
    myCollection[i].AgeOutVal--;

    if(myCollection[i].AgeOutVal == 0)
    {
       myCollection.Remove(i);
       i--;
    }
}

但是我收到编译器错误,表明我不能使用这样的集合。有什么好的/快速的方法来做到这一点?

【问题讨论】:

  • 结构不应该是可变的。您使用的类型几乎可以肯定是类,而不是结构。
  • 更不用说当你删除一个项目时,当i 不断增加到原来的长度时,你最终会跳过下一个项目并跑出集合的末尾。
  • 您遇到的编译器错误是什么。
  • 您可能想多解释一下您的预期使用模式。结构数组对于随机和顺序访问以及紧凑的内存布局都具有非常好的性能。也适用于将项目附加到末尾。如果您需要删除中间的元素,则不必那么多。其他数据结构(例如优先级队列)可能更适合您的特定用例。我们无法确定,因为您的问题中没有足够的信息。
  • 您可能希望使用 (1) 为接收流并按顺序处理它而优化的结构(例如环形缓冲区) (2) 不同的结构来存储您需要“挂起”的“点”到”。同样,如果您在问题中更清楚地说明您的预期用途,您将获得更好的答案。我建议你edit它并添加你的具体使用场景。

标签: c# collections linked-list


【解决方案1】:

我建议您首先对程序进行一些认真的性能分析。每秒处理一百万个项目只会给每个项目留下几千个周期,这当然是可行的。但是有了这种性能目标,您的性能将受到数据局部性和由此产生的缓存未命中等因素的严重影响。

其次,我建议您将“这个东西是否需要从队列中删除”的关注与对象本身所代表的任何关注分开。

第三,你不说“年龄”字段能有多大,只是说它在倒计时。每次通过循环改变整个集合只是为了找到要删除的集合似乎效率低下。一些想法:

  • 假设“年龄”从十倒数到零。与其创建一个集合并且集合中的每个项目都有一个年龄,不如创建 10 个集合,一个用于将超时的事物,一个用于将超时的事物,以此类推。每打勾,您丢弃“一次超时”集合,然后“两次超时”集合变成“一次超时”集合,依此类推.每次通过循环时,您只需移动少量的集合引用,而不是改变大量的项目。

  • 为什么“年龄”在倒计时?时间在增加。根据创建时间标记每个项目,并且永远不要更改它。使用队列,因此您可以在一端插入新项目并从另一端删除它们。因此,队列将按年龄排序。每次滴答,都会将太旧的项目出列,直到您到达不太旧的项目。如其他地方所述,队列的循环缓冲区实现可能是有效的。

【讨论】:

  • 在某些情况下,与其在创建时间进行记录,不如在到期时间或应该采取行动的时间进行记录,以防您只需要处理接下来是最旧的项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多