【发布时间】:2016-11-01 15:14:19
【问题描述】:
我想实现一个包含时间序列数据的 c# 类 (.NET 4.6.1),如下所示:
- timeseries 是一个以 DateTime 为键的集合,每个都有一个关联的值(例如一个双精度数组)
- 积分将严格按时间顺序添加
- 会有一个滚动时间段 - 例如1 小时 - 添加新点时,开始时超过此时间段的所有点都将被删除
- 性能的关键问题将是快速添加新点,并找到特定时间的数据点(二分搜索或更好的搜索是必不可少的)。有时集合中会有 100k 的点数。
- 它必须是线程安全的
- 它必须具有相对的内存效率 - 例如它不能只保留从一开始的所有点 - 随着时间的推移,内存占用必须相当稳定。
那么就底层集合类而言,什么是好的方法呢?使用列表会很慢——因为滚动周期意味着我们需要从列表的开头删除很多内容。 Queue 或 LinkedList 可以解决这个问题 - 但我不认为它们提供了访问集合中第 n 个项目的快速方法(ElementAt 只是迭代,所以非常慢)。
我能想到的唯一解决方案是将数据存储两次——一次存储在一个易于从一开始就删除的集合中——另一次存储在一个易于搜索的集合中(使用一些糟糕的后台进程来修剪过时的点以某种方式从搜索集合中获取)。
有没有更好的方法来解决这个问题?
谢谢。
【问题讨论】:
-
为什么List会慢,最后删除项目应该是O(1)
-
但是要修剪陈旧的数据,我必须从列表的开头删除项目 - 我认为当列表很大时这会很慢。
-
我的错 - 这是 O(Count) 而不是 O(count) :-)
-
您可能想查看
SortedList<TKey, TValue>,您只需要在每次读取或写入访问时用ReaderWriterLockSlim将其包装起来,以使其线程安全。 -
SortedList 的问题在于它从列表开头删除项目也很慢 - 即它的 O(n) - 当集合中有 100k+ 个项目时非常慢。
标签: c# performance collections time-series