保存数据列表并在更改数据列表时使其可读的最快方法

本文关键字:数据 列表 方法 保存 | 更新日期: 2024-10-24 10:11:01

我有一个类Data,我想在固定的天数内保存一些Data对象列表。

我可以这样做:List<List<Data>>List<Data>[amount]Dictionary<DateTime, List<Data>>或任何我想要的东西。

例如,我有从 1.1.2000 到 4.1.2000 的数据。

我现在想把它移到:2.1.2000 到 5.1.2000(将来移动一天(
所以我必须删除第一个并在最后移动和添加新数据。

我还需要另一种方式:31.12.1999 到 3.1.2000(过去移动一天(
现在我必须删除最后一个并在开头移动和插入新数据。

的问题:当我从该结构读取数据时,我异步加载数据。我希望,每次都可以读取数据。

所以。最好的方法是什么?当我填写数据时,数组是最快的方法。 List<List<Data>>也很好,字典很慢(在我的测试中,两者在 0.5 秒左右,而 Dic 大约 2 秒(。

但是当我想移动该数组时,当我还没有准备好移动数据时,我无法读取。当我使用列表时,我不必触摸中间(只先删除并在末尾添加;更快?(并且使用字典我可以一直访问?

数据

保存了大约 10.000 个数据集,我通常在列表中有大约 10 个数据元素。我有大约 3-4 天的负载。

编辑:

目标是使用 mschart 在图表中显示部分数据。我读取文件,将它们加载到我的结构(我的List<List<Data>>或其他什么(中并将数据转换为Charting.DataPointCollection并让图表显示它(直接转换数据并持有DataPointCollection而不是Data似乎没有去,请参阅我的问题:图表.数据点集合如何获取范围?

当我想获得一些信息时,例如 2.1.2000 8:00 到 10:00,我在我一天的结构中搜索(我搜索正确的List<Data>(,然后我选择正确的数据集(在List<Data>中搜索(,然后我在Data中搜索正确的数据点。
我收集它们并应用一些算法来减少数据点(例如Douglas-Peucker(。之后,我将数据提供给图表。

当我只加载没有结构的数据点时,我的图表太慢了。

为了使用户能够继续前进(无需等到数据加载(,我需要预加载数据。这就是为什么我再加载几天异步。
在这种情况下,用户可以移动,当需要邻居日时,我可以显示预加载的数据并在下一个需要的日期异步加载。

保存数据列表并在更改数据列表时使其可读的最快方法

更新

事实证明,您正在寻找的东西有一个名称:deque。Deque 是双端队列的缩写,该队列允许在两端插入/删除。

我实现了:

  • 并发无锁ConcurrentDeque<T>,两端都有窥视、弹出和推送操作,似乎非常适合您的需求;
  • 和更简单的非并发Deque<T>.

可以在 GitHub 上找到源代码(随意贡献(和 NuGet 包:https://www.nuget.org/packages/DequeNET/

旧答案

听起来像是对ConcurrentQueue<T>的完美描述,一种线程安全的FIFO(先进先出(数据结构。

使用 Enqueue 将项目添加到队列的后面,TryDequeue删除队列的头部。

其他线程仍然可以循环访问集合:GetEnumerator 实现在调用时返回集合的快照。


字典绝对不是一个好主意。看起来您希望按插入顺序对项目进行排序:字典(哈希表(不保证元素的顺序。

你可以

有一个Dictionary<DateTime,List<Data>>。现在,当新数据到达时,您可以调用如下函数:

TimeSpan tsNumberOfDaysToHoldData=TimeSpan.FromDays(5);
var DataHolder= new Dictionary<DateTime,List<Data>>()
private void AddNewDayData(DateTime NewDay,List<Data> NewData)
{
   DataHolder[NewDay]=NewData;
   List<DateTime> ExpiredDates=new List<DateTime>();
   foreach(var DayCursor in DataHolder.Keys)
   {
       if(NewDay-DayCursor>tsNumberOfDaysToHoldData)
       {
         ExpiredDates.Add(DayCursor);
       }
   }
   ExpiredDate.ForEach(c=>DataHolder.Remove(c))
 }

此函数检查字典中的所有键,标记表示过期日期的键,并将它们从 DataHolder 中删除。