当前位置:
首页 > Python基础教程 >
-
C#教程之lamdba 性能测试 大数据内存查找
由于工作中需要对大量数据进行快速校验,试验采用读入内存List实体采用lamdba查找来实现。
实际需求:实际读入内存数据 50W条记录主集数据,还包含约20个子集,子集最大记录数300W条记录。读入内存,校验出结果5分钟之内完成。
测试数据读入内存后占用约2-3G内存。这里测试了多线程读取数据,但提速效果并不明显。SQLServer有自己的SQL执行排队机制(读入数据过程遇到一个小插曲,读入速度慢,占用内存大,无意中发现是把记录照片流也读入了内存。实际处理数据过程并不需要照片信息。去掉后速度提升很大,占用内存也缩小很多,以后遇到类似操作应提前排除这类情况了)
数据校验脚本由另一个同事写的,大约有500个校验,实体字段合法性校验,及主集子集关联检验。开始拿到脚本丢进去测试,结果半个小时也没反应。果断结束进程。然后就是痛苦的优化过程,曾经怀疑这样的方式行不通。差不多用了两周时间,达到5000个主集信息10秒以内完成。50W数据也在3-5分钟完成。最后完成100个并发测试。校验结果正常返回。一切OK现已正常上线使用。
以下是在本次数据校验实现过程中总结出来应注意的一些地方。
1、由原来数据库校验改为内存校验,内存速度更快,数据库校验还会带来并发等待,死锁等问题。
2、加载数据可以采用多线程加载
3、主键使用整形加快查询速度 这一点特别重要,速度提升上千倍。
4、采用lamdba表达式查找数据 用联合查询代替for循环
5、根据数据量的大小采用分别采取线性查找或二分查找提高查询速度
6、共用数据只取一次,在整个校验中全局使用。
并发测试 时发现 静态类中的静态属性不是安全的 因为静态类在内存中只有一份 去掉static 后多线程测试正常
以下为测试数据,及相关说明,可以直接忽略。感兴趣的的可以看看。
1、7万条记录
A01.FindAll(x => !x.PersonStatus.In("01", "02", "03", "04"))
循环查找,共加载15298人,耗时:0.019519秒.
A01.FindAll(x => !(x.PersonStatus == "01" || x.PersonStatus == "02" || x.PersonStatus == "03" || x.PersonStatus == "04"))
循环查找,共加载15298人,耗时:0.0284169秒.
2、3.3万条记录 x.CodeID == "ZB01"的有3300条记录
Codes.FindAll(x => x.CodeID == "ZB01" && (x.CodeItemName == "市辖区" || x.CodeItemName == "县"))
循环查找,共加载287人,耗时:0.0139286秒.
Codes.FindAll(x => x.CodeID == "ZB01" && (x.CodeItemName.In("市辖区", "县")))
循环查找,共加载287人,耗时:0.0230568秒.
3、4000条记录 codeIds有3300条记录
personTableList.A01.FindAll(x => !x.A0114.In(codeIds));
A01 4000条记录 循环查找,共加载0人,耗时:0.1066983秒.
A01 7万条记录 循环查找,共加载0人,耗时:1.7386399秒.
foreach (var A01 in personTableList.A01)
{
if (!codes.Exists(x => x.CodeItemID == A01.A0114))
{
persons.Add(A01);
}
}
上面形式代码,两个列表都是7W条记录时
循环查找,共加载75601人,耗时:55.4800723秒.
循环查找,共加载75601人,耗时:107.4412256秒.
3、
A01.FindAll(x => x.W0111G == "")
循环查找,共加载183人,耗时:0.0039961秒.
A01.FindAll(x => x.W0111G.IsSame(""))
循环查找,共加载183人,耗时:0.0307353秒.
A01.FindAll(x => ids2.IndexOf(x.PersonID)) 最快
A01.FindAll(x => x.PersonID.In(personIds)) 第二
A01.FindAll(x => ids2.Contains(x.PersonID)) 第二
A01.FindAll(x => ids2.Exists(p=>p == x.PersonID)) 最慢
联合查询 速度快
var query = (from A14 in DataList.A14
join A01 in DataList.A01
on A14.ID equals A01.ID
select new { A14.ID, A14.A1407, A01.A0141 }).ToList();
personIds = query.FindAll(x => x.A0141 > x.A1407)
非常重要 主键字段 整形字段比字符串快上百倍
线性查找:Contains,Find,IndexOf都是线性查找。
二分查找:BinarySearch,因为二分查找必须是对有序数组才有效,所以查找前要调用List的Sort方法。
结论:如果List项的个数比较小,用线性查找要略快于二分查找,项的个数越多二分算法优势越明显。可根据实际情况选用适合的查找方式。
测试数据2条
耗时:0.0186627秒.
二分耗时:0.0356611秒.
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式