List<T>与Dictionary<string,T>频繁检索的性能差距
一直对LINQ简洁高效的语法青睐有加,对于经常和资料库,SQL语法打交道的C#开发者来说,LINQ无疑是一个非常不错的选择,当要在List<T>(T为一个普通对象)集合中查找满足某些条件的某个对象时,写成 form t in T where t. Property1 == "A" && t. Property2== "B" …select t或者写成T.Where(t=>t. . Property1 == "A" && t. Property2== "B" …),是再自然不过的了。乍看之下,反正List<T>已被存在记忆体,无需顾忌反复查询所产生的连续成本,而且where条件也十分通俗易懂。但是当你需要频繁检索某个集合中的满足某些条件的对象时,比如需要求两个集合中的差集时,你有没有考虑过性能问题呢?最近的项目遇到频繁检索资料库,对比查询的多个对象的性能瓶颈问题,于是做了下面这个测试,下面我们来看一个对比测试:
public static class LinqOrDictioanry { public static string GetLinqSingle(List<Model> model, string id, string sbName) { return model.Single(o => o.Id == id && o.SbName == sbName).JuName; } public static string GetDictionaryValue(Dictionary<string, Model> dictionaryModel, string id, string sbName) { return dictionaryModel[string.Format("{0}\t{1}", id, sbName)].JuName; } }
[TestMethod] public void TestMethod1() { var model = new List<Model>(); ; ; var random = new Random(count); ; i < count; i++) { model.Add(new Model() { Id = Guid.NewGuid().ToString(), JuName = , ), SbName = , ), Dydj = , ), ZhangChang = , ), YcHang = , ), Time = DateTime.Now, Total = random.Next(, ) }); } var dictionary = model.ToDictionary(d => string.Format("{0}\t{1}", d.Id, d.SbName), d => d); var toModel = new List<Model>(); , ); ; i < tempCount; i++) { var sample = model[random.Next(model.Count)]; toModel.Add(new Model() { Id = sample.Id, SbName = sample.SbName }); } Console.WriteLine("Count={0}>{1}", model.Count, tempCount); ; i < time; i++) { Console.WriteLine("第 {0}次检索{1} 个对象", i, tempCount); var sw = new Stopwatch(); sw.Start(); ; j < tempCount; j++) { var model1 = toModel[j]; model1.JuName = LinqOrDictioanry.GetLinqSingle(model, model1.Id, model1.SbName); } sw.Stop(); Console.WriteLine("耗时 {0}ms", sw.ElapsedMilliseconds); Console.WriteLine(].JuName, toModel[tempCount / ].JuName, toModel[tempCount - ].JuName); } Console.WriteLine(""); ; i < time; i++) { Console.WriteLine("第 {0}次检索{1}个对象", i, tempCount); var sw = new Stopwatch(); sw.Start(); ; j < tempCount; j++) { var model1 = toModel[j]; model1.JuName = LinqOrDictioanry.GetDictionaryValue(dictionary, model1.Id, model1.SbName); } sw.Stop(); Console.WriteLine("耗时 {0}ms", sw.ElapsedMilliseconds); Console.WriteLine(].JuName, toModel[tempCount / ].JuName, toModel[tempCount - ].JuName); } }
随机构造一个容量为10万的List<T>集合和Dictionary<string,T>集合,产生一个随机数作为检索的“频率”,也就是在这10万个对象中要检索的次数(这里产生了1639个检索对象),执行结果让人大吃一惊,耗时相差尽然如此之大。
从测试结果来看,两者的效率天壤之别,而且随着检索集合的容量大小和检索频率成”正比”趋势: 使用LINQ Where检索,执行三次平均检索1600多次13秒左右;而Dictionary执行三次检索1600多次也不超过10ms! LINQ to Object的Where的查询不像数据库可以靠索引加速检索,当查询元素的对象很多,并且查询检索非常频繁时,可以考虑使用Dictionary<string, T>等做法取代Where条件检索,避免不必要的性能损失。
结论:依赖LINQ的Where查询在大量资料库中频繁检索数据是,很容易形成效率瓶颈。遇到这样的需求,可通过ToDictionary()简单转换成Dictionary,可以获得大幅度的性能提升。
有人质疑list 转成 dictionary 的时间开销,这里就把本测试的list 转成 dictionary 的时间开销也发出来,
鄙人能力有限,以上测试纯属个人知识点查缺补漏应用,不敢强加应用场景,以免误人子弟,若有不妥或者错误的地方,还望各位大神斧正。
List<T>与Dictionary<string,T>频繁检索的性能差距的更多相关文章
- 关于 Dictionary<string,string>,和List<T>在View的使用
在MVC中Dictionary<string,string>如何应用到View页面中呢,例: <input type="text" name=key value= ...
- MVC 自定义IModelBinder实现json参数转Dictionary<string, string>
IModelBinder的学习不算深入,现在用它来实现一个json转Dictionary<string, string> 一.原始json转Dictionary<string, st ...
- C#基础总结之五Dictionary<string, string[]>和while循环
#region 第五天作业 名片集(01) //Dictionary<string, string[]> PersonCard = new Dictionary<string, st ...
- convert NameValueCollection/Dictionary<string, object> to JSON string
public static class WebExtension { public static T Decode<T>(this RequestBase res) { Type type ...
- Dictionary<string, string> 排序
.net framework 2.0 版 Dictionary<string, string> collection = new Dictionary<string, string& ...
- QueryString to Dictionary<string, string>
public class ModelConvertHelper<T> where T : new() {// 此处一定要加上new() public static IList<T&g ...
- Dictionary<string, object>
Dictionary<string, object> dcic = JsonHelper.DataRowFromJSON(resultdepth); foreach (var depthk ...
- Dictionary<string, object>不区分大小写
Dictionary<string, object> dic = new Dictionary<string, object>(StringComparer.OrdinalIg ...
- C#将URL中的参数转换成字典Dictionary<string, string>
/// <summary> /// 将获取的formData存入字典数组 /// </summary> public static Dictionary<String, ...
随机推荐
- Spring boot 基于Spring MVC的Web应用和REST服务开发
Spring Boot利用JavaConfig配置模式以及"约定优于配置"理念,极大简化了基于Spring MVC的Web应用和REST服务开发. Servlet: package ...
- Parameter 'id' not found. Available parameters are [1, 0, param1, param2]异常
出现此类异常可能的原因:Mapper.xml文件中的parameterType的类型与传入的参数类型不匹配
- .NET框架设计(常被忽视的框架设计技巧)
阅读目录: 1.开篇介绍 2.元数据缓存池模式(在运行时构造元数据缓存池) 2.1.元数据设计模式(抽象出对数据的描述数据) 2.2.借助Dynamic来改变IOC.AOP动态绑定的问题 2.3.元数 ...
- SQL Server中字符串转化为GUID的标量函数实现
还是工作中遇到的需求,有时候和外部的系统对接,进行数据的核对功能,外部的系统有时候主键字段列数据类是UNIQUEIDENTIFER(GUID)类型的字符串格式,去除了GUID格式中的分隔符“- ...
- (转)Java 详解 JVM 工作原理和流程
作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java虚 ...
- Linux系统监控命令之iotop
iotop命令 iotop命令是一个用来监视磁盘I/O使用状况的top类工具.iotop具有与top相似的UI,其中包括PID.用户.I/O.进程等相关信息.Linux下的IO统计工具如iostat, ...
- linux关于文件的那些事儿
一个文件的权限对于系统的安全来说是很重要的,linux是一个支持多任务多用户的系统,我们都不希望一些自己的文件被别人看到或者修改! 对于一个文件的权限我们可以用 ls -l 命令来查看,例如: [ro ...
- KEIL MDK STM32如何建立工程
2. 3 4 5 6 7 QQ 463431476 8 9
- linux下 ^M
在Linux下使用vi来查看一些在Windows下创建的文本文件,有时会发现在行尾有一些“^M”.有几种方法可以处理. 注意:在Linux下,可以通过ctrl+v,ctrl+m,打出^M字符.而却,以 ...
- 使用virt-manager创建和管理虚拟机
1.虚拟机管理程序和虚拟机管理 一个服务器上只安装单一操作系统的时代已经过去,单个服务器可通过安装多个虚拟机来运行不同操作系统.虚拟机的大量使用减少了所需的服务其硬件,降低了服务器的功耗,但却带来了另 ...