由于工作中需要对大量数据进行快速校验,试验采用读入内存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秒.
 
 

lamdba 性能测试 大数据内存查找的更多相关文章

  1. JAVA 大数据内存耗用测试

    JAVA 大数据内存耗用测试import java.lang.management.ManagementFactory;import java.lang.management.MemoryMXBean ...

  2. pymysql 读取大数据内存卡死的解决方案

    背景:目前表中只有5G(后期持续增长),但是其中一个字段(以下称为detail字段)存了2M(不一定2M,部分为0,平均下来就是2M),字段中存的是一个数组,数组中存N个json数据.这个字段如下: ...

  3. 大数据学习笔记之Hadoop(一):Hadoop入门

    文章目录 大数据概论 一.大数据概念 二.大数据的特点 三.大数据能干啥? 四.大数据发展前景 五.企业数据部的业务流程分析 六.企业数据部的一般组织结构 Hadoop(入门) 一 从Hadoop框架 ...

  4. 从Hadoop框架讨论大数据

    [Hadoop是什么?] 1)Hadoop 是一个由 Apache 基金会所开发的分布式系统基础架构. 2)主要解决,海量数据的存储和海量数据的分析计算问题. 3)广义上来说,HADOOP 通常是指一 ...

  5. 啃掉Hadoop系列笔记(01)-Hadoop框架的大数据生态

    一.Hadoop是什么 1)Hadoop是一个由Apache基金会所开发的分布式系统基础架构 2)主要解决,海量数据的存储和海量数据的分析计算问题. 3)广义上来说,HADOOP通常是指一个更广泛的概 ...

  6. BAT推荐免费下载JAVA转型大数据开发全链路教程(视频+源码)价值19880元

    如今随着环境的改变,物联网.AI.大数据.人工智能等,是未来的大趋势,而大数据是这些基石,万物互联,机器学习都是大数据应用场景! 为什么要学习大数据?我们JAVA到底要不要转型大数据? 好比问一个程序 ...

  7. Java转型大数据开发全套教程,都在这儿!

    众所周知,很多语言技术已经在长久的历史发展中掩埋,这期间不同的程序员也走出的自己的发展道路. 有的去了解新的发展趋势的语言,了解新的技术,利用自己原先的思维顺利改变自己的title. 比如我自己,也都 ...

  8. 大数据技术之Hadoop入门

      第1章 大数据概论 1.1 大数据概念 大数据概念如图2-1 所示. 图2-1 大数据概念 1.2 大数据特点(4V) 大数据特点如图2-2,2-3,2-4,2-5所示 图2-2 大数据特点之大量 ...

  9. Hadoop基础(二):从Hadoop框架讨论大数据生态

    1 Hadoop是什么 2 Hadoop三大发行版本 Hadoop三大发行版本:Apache.Cloudera.Hortonworks. Apache版本最原始(最基础)的版本,对于入门学习最好. C ...

随机推荐

  1. Centos修改系统语言

    使用man page帮助时,发现居然是中文的,不过想想即便英语再水,也要逼着自己去适应.于是百度找了一下修改系统语言的方法. 首先使用 locale 命令查看当前的系统语言 然后修改时一般有两种方法, ...

  2. pycharm Django

    上面的两张图片,是Django项目出错的图片,记得以前也出现过这个情况,当时好像是关闭了一些端口程序,后来就可以了,但是忘记了,那个链接也找不到了,所以现在很困惑,再找找. 电脑上现在程序安装的太多, ...

  3. RabbitMQ入门_05_多线程消费同一队列

    A. 多线程消费同一队列 参考资料:https://www.rabbitmq.com/tutorials/tutorial-two-java.html 消费一条消息往往比产生一条消息慢很多,为了防止消 ...

  4. hdoj4283 You Are the One

    题意:每个人出场时获得等待时间*值的unhappy值.有个栈换出场顺序.问怎样最小? 一开始的时候觉得在中间取断点,dp[i][j]表示区间全出场后的最小值.那么dp[i][j]=dp[i][k]+d ...

  5. android------2018 年初值得关注的 16 个新 Android 库和项目

    1. transitioner Transitioner 是一个为两个拥有嵌入子视图的视图之间提供简便.动态且可调整的动画效果的库.它纯 100% 使用 Kotlin 编写而成,使用 MIT 许可,且 ...

  6. C++ vector 实现二维数组

    在STL中Vector这一容器,无论是在封装程度还是内存管理等方面都由于传统C++中的数组.本文主要是关于使用Vector初始化.遍历方面的内容.其他二维的思想也是类似的. 这里简单叙述一下C++ 构 ...

  7. 关于一些逗逼函数//atoi,itoa,strtok,strupr,

    reverse(begin,end)  反转容器内容可以是string,char数组,也可以是int型数组...用于反转其中的内容: char *   strtok(cahr *,const char ...

  8. $LANG、$NLS_LANG 记录一下

    环境:linux $LANG 为linux termal终端环境下的 语言环境 $NLS_LANG  为oracle数据库中 会话中的语言环境. 个人理解,望大家补充

  9. linux tcpdump 抓包

    tcpdump是linux命令行下常用的的一个抓包工具,记录一下平时常用的方式,测试机器系统是ubuntu 12.04. tcpdump的命令格式 tcpdump的参数众多,通过man tcpdump ...

  10. JVM笔记(一) Java内存区域

    Java 内存区域 总概 java虚拟机在执行java程序的过程中,会把它管理的内存划分为几个不同的数据区域.每当运行一个java程序时,就会启动一个虚拟机. 具体的区域如图所示: 同时,方法区 与 ...