C#当动态数据过大画图有困难时怎么办?

news/2025/2/13 1:05:11/

笔者最近写了一个监控软件, 数据量较大, 而所用插件刷新有压力. 所以就写了一个支持数据抽取的大数据维护类.

        // 设计需求:// 会发生数据的新增, 并且在数据达到上限时自动去掉前半截数据,// 高频的等间隔读取抽有数据,// 数据结构大小是可以在生成对象时提供, 并且对不提供大小参数的情况下使用默认大小// 数据量较大(大约有40万个元素),// 支持等距提取若干个数据,//      比如从最后20000个树种提取2000个数据(可通过参数设置这个数量),//      提取的规则是:返回提取的数据量, 将提取的数写入到调用者提供的list中// 设计思路:// 使用List<T> 或LinkedList<T>都有一些弊端:// List<T> 在去除数据时,需要将后半部分的数据移动到前面,对于大数据量来说,性能开销较大。// LinkedList<T> 在随机访问数据时,效率较低,因为需要从头开始遍历到目标位置。// 在C#中,没有现成的数据结构可以同时满足这些需求。因此,自己设计一个数据结构来实现这些功能。// 将两个List<T>结合使用,每个List<T>存储一半的数据。当数据达到上限时,丢弃第一个List<T>,并创建一个新的List<T>来存储新的数据。public interface IDataExtractor{void ExtractDataFromEnd(int lastCount, int extractCount, List<int> targetList);}public class LargeDataStructure : IDataExtractor{private const int DefaultHalfMaxRecordsNum = 60 * 60 * 24 * 7 * 2; // Default half of max recordsprivate int halfMaxRecordsNum;private List<int> firstHalf;private List<int> secondHalf; public int AllDataCount => firstHalf.Count + secondHalf.Count;public LargeDataStructure(int? maxRecordsNum = null){this.halfMaxRecordsNum = (maxRecordsNum ?? DefaultHalfMaxRecordsNum) / 2;this.firstHalf = new List<int>(halfMaxRecordsNum);this.secondHalf = new List<int>(halfMaxRecordsNum);}public void Append(int data){if (secondHalf.Count >= halfMaxRecordsNum){// Discard the first half and move the second half to the firstfirstHalf = secondHalf;secondHalf = new List<int>(halfMaxRecordsNum);}if (firstHalf.Count < halfMaxRecordsNum){firstHalf.Add(data);}else{secondHalf.Add(data);}}public int this[int index] // indexer{get{if (index < halfMaxRecordsNum){return firstHalf[index];}else{return secondHalf[index - halfMaxRecordsNum];}}}public void ExtractDataFromEnd(int lastCount, int extractCount, List<int> targetList){targetList.Clear();int startIndex = Math.Max(0, AllDataCount - lastCount);int validCount = AllDataCount - startIndex;if (extractCount >= validCount){// 提取的数量大于等于最后的数据量for (int i = startIndex; i < AllDataCount; i++){targetList.Add(this[i]);}}else{double interval = (double)(validCount-1) / (extractCount - 1); // 计算浮点数等距间隔for (int i = 0; i < extractCount; i++){int index = (int)Math.Round(startIndex + interval * i);index = Math.Min(index, AllDataCount - 1); // 确保不超过数据范围targetList.Add(this[index]);}}}}private void TestExtractDataFromEnd(){LargeDataStructure dataStructure = new LargeDataStructure();// 添加一些数据用于测试for (int i = 0; i < 20; i++){dataStructure.Append(i);}List<int> result = new List<int>();// 用例1.测试数据量不足,提取 30 个数据dataStructure.ExtractDataFromEnd(50, 30, result);Console.WriteLine("数据量不足,提取 30 个数据:");foreach (int data in result){Console.Write(data + " ");}Console.WriteLine();// 再添加一些数据用于测试for (int i = 20; i < 100; i++){dataStructure.Append(i);}// 用例2.测试整数等距提取,提取 5 个数据dataStructure.ExtractDataFromEnd(10, 5, result);Console.WriteLine("整数等距提取(10个数据中提取5个):");foreach (int data in result){Console.Write(data + " ");}Console.WriteLine();// 用例3.测试浮点数等距提取,提取 20 个数据dataStructure.ExtractDataFromEnd(30, 20, result);Console.WriteLine("浮点数等距提取(30个数据中提取20个):");foreach (int data in result){Console.Write(data + " ");}Console.WriteLine();// 用例4.测试尾部数超过需求数, 想从5个数中提取100个(不合法参数dataStructure.ExtractDataFromEnd(5, 100, result);Console.WriteLine("尾部数超过需求数(5个数据中提取100个):");foreach (int data in result){Console.Write(data + " ");}Console.WriteLine();Console.ReadLine();}

当涉及处理大量数据时,LargeDataStructure类可以作为一个有用的工具。

该类可以存储大量数据,并提供了一些功能来操作和提取这些数据。以下是LargeDataStructure类的总结:

  1. LargeDataStructure类的目的是处理大量数据,它被设计为实现IDataExtractor接口。

  2. LargeDataStructure类内部使用两个List<int>对象(firstHalf和secondHalf)来存储数据。这两个列表分别表示数据的前半部分和后半部分。

  3. 构造函数LargeDataStructure(int? maxRecordsNum = null)允许你创建一个LargeDataStructure对象,并可选地指定最大记录数(maxRecordsNum)。如果未提供最大记录数,将使用默认值。

  4. 方法Append(int data)用于将数据添加到LargeDataStructure对象中。如果secondHalf列表的大小达到最大记录数的一半(halfMaxRecordsNum),则会丢弃firstHalf列表中的数据,并将secondHalf作为新的firstHalf。然后,创建一个新的空的secondHalf列表来接收后续的数据。

  5. LargeDataStructure类还提供了索引器(this[int index]),允许你通过索引访问LargeDataStructure对象中的数据。该索引器考虑了数据的分布,以正确地获取指定索引位置的数据。

  6. 方法ExtractDataFromEnd(int lastCount, int extractCount, List<int> targetList)允许你从LargeDataStructure对象的末尾提取指定数量的数据。你可以指定最后的数据数量(lastCount),要提取的数据数量(extractCount)以及目标列表(targetList)来接收提取的数据。

  7. 如果提取的数量大于等于最后的数据数量,ExtractDataFromEnd方法将提取所有最后的数据。否则,它将根据浮点数等距间隔从数据中提取相应数量的数据。在计算浮点数等距间隔时,会考虑有效数据的数量,以确保提取不超过数据的范围。

LargeDataStructure类提供了一种高效且灵活的方式来处理大量数据,并具有数据添加、数据访问以及从数据末尾提取数据的功能。这个类可以根据你的需求进行进一步的扩展和定制。


http://www.ppmy.cn/news/387908.html

相关文章

Go语言并发范式-future模式

1、Go语言并发范式-future模式 编程中经常遇到在一个流程中需要调用多个子调用的情况&#xff0c;这些子调用相互之间没有依赖&#xff0c;如果串行地调用&#xff0c;则耗 时会很长&#xff0c;此时可以使用Go并发编程中的future模式。 future模式的基本工作原理&#xff1…

如何选择到最合适的DDoS缓解服务?

DDoS缓解服务提供商的数量可能很多&#xff0c;但只有一些提供商提供高效服务的所有必要功能&#xff0c;因此如果要选择正确的 DDoS保护解决方案&#xff0c;必须考虑以下因素&#xff1a; 1.缩小风险范围 选择DDoS缓解服务的第一步&#xff0c;确定您组织的特定需求&#…

视觉SLAM十四讲——ch7实践(视觉里程计1)

视觉SLAM十四讲----ch7的实践操作及避坑 1. 实践操作前的准备工作2. 实践过程2.1 特征提取与匹配2.2 对极几何2.3 三角测量2.4 求解PnP2.5 求解ICP 3. 遇到的问题3.1 准备工作遇到的问题 1. 实践操作前的准备工作 在终端中进入ch7文件夹下&#xff0c;顺序执行以下命令进行编译…

知乎视频发布软件使用方法视频

知乎视频发布软件使用方法视频&#xff0c;知乎批量发布软件效果怎么样 #小红书视频上传#抖音seo软件#网络推广#视频营销 软件有月卡、季卡、半年卡、年卡 【其中推荐&#xff1a;百家号 哔哩哔哩B站&#xff0c;微博等软件发帖】 服务时间&#xff1a;&#xff08;8&#xf…

element UI日历组件自定义操作设置农历、阳历、节日展示、单日操作

图例&#xff1a; 自定义calendar.js,其他页面直接引入就可以 /** * 1900-2100区间内的公历、农历互转 * charset UTF-8 * Author Jea杨(JJonlineJJonline.Cn) * Time 2014-7-21 * Time 2016-8-13 Fixed 2033hex、Attribution Annals * Time 2016-9-25 Fixed lunar …

跟我volatile从表面到底层

原文来自我的博客月泉的博客 食用该篇文章&#xff0c;作者建议你最好已经提前了解过&#xff1a;JMM以及CPU缓存一致性协议还有相关的内存屏障的知识并且能够理解CPU的乱序执行&#xff0c;如果作者理解不当&#xff0c;欢迎指出。 如果本文对你有所帮助不妨给 博客的Github点…

volatile从表面到底层

该篇文章讨论的议题&#xff1a; java语义上的volatile内存屏障JVM的实现生成的汇编指令如何保障的的可见性和有序性为什么volatile不能保证复合操作的原子性 java语义上的volatile 我们从一个很常见的案例开始出发 public class Test {public static void main(String[] a…

带卷积核的神经网络的迭代次数与收敛标准的关系

制作一个带有卷积核的神经网络让这个网络向1,0收敛,y[0]向1收敛&#xff0c;y[1]向0收敛。收敛标准用δ表示,当满足条件 while(Math.abs(y[0]-1)> δ || Math.abs(y[1]-0)> δ ) 网络开始迭代&#xff0c;本文尝试了1e-3到9e-7共21个收敛标准&#xff0c;记录每个收敛…