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, ...
随机推荐
- java.lang.NoClassDefFoundError:TagSupport
这个错误应该就是没有成功加载tomcat自带的jar包jsp-api.jar. 在网上看到很多网友说要把tomcat/lib下的jsp-api.jar拷贝到项目/WEB_INF/lib下并导入,本人试 ...
- 烂泥:nginx同时支持asp.net与php
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 经过两天的实验,终于让nginx同时支持asp.net与php了.下面就把具体的配置过程记录如下. 注意:本次实验OS:centos6 64bit. 尽 ...
- jsp html5 video实现在线视频播放源码,支持IE6,7,8,10,11,谷歌,火狐等浏览器
jsp源码: <%@ page language="java" import="java.util.*" pageEncoding="utf-8 ...
- 工作中常用的Linux命令:ipcs/ipcrm命令
本文链接:http://www.cnblogs.com/MartinChentf/p/6057100.html (转载请注明出处) ipcs 1. 命令格式 ipcs [resource-option ...
- android 判断字符串是否为空与比对["=="与equals()的区别]
if (s == null || s.equals("")) ; } s.equals("")里面是要比对的字符串 声明字符串未赋初始值或值,然后比对就会出错, ...
- @Value取不到值引出的spring的2种配置文件applicationContext.xml和xxx-servlet.xml
项目中经常会用到配置文件,定义成properties的形式比较常见,为了方便使用一般在spring配置文件中做如下配置: <context:property-placeholder ignore ...
- js对已经对象类型进行类型辨别
typeof() Object.prototype.toString.call(data)
- 新手必学的java报表开发工具FineReport实用技巧
1.在制作模板时,如何将报表中的值传递到超链接网页呢? 在项目中以frame方法把F1.CPT放到项目的页面中,对F1.CPT做网络报表超链接F2.CPT,然后在F2.cpt页面中,做个超链接的网页, ...
- 准备使用 Office 365 中国版--安装
温故而知新,先附上一个链接:Office 365常见问题 Office 365中Office套件的安装介质和传统Office套件的安装介质是有些区别的,虽然功能都一样.因此,如果购买了带Office套 ...
- Caffe 抽取CNN网络特征 Python
Caffe Python特征抽取 转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ Caffe大家一般用到的深度学 ...