一直对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>频繁检索的性能差距的更多相关文章

  1. 关于 Dictionary<string,string>,和List<T>在View的使用

    在MVC中Dictionary<string,string>如何应用到View页面中呢,例: <input type="text" name=key value= ...

  2. MVC 自定义IModelBinder实现json参数转Dictionary<string, string>

    IModelBinder的学习不算深入,现在用它来实现一个json转Dictionary<string, string> 一.原始json转Dictionary<string, st ...

  3. C#基础总结之五Dictionary<string, string[]>和while循环

    #region 第五天作业 名片集(01) //Dictionary<string, string[]> PersonCard = new Dictionary<string, st ...

  4. convert NameValueCollection/Dictionary<string, object> to JSON string

    public static class WebExtension { public static T Decode<T>(this RequestBase res) { Type type ...

  5. Dictionary<string, string> 排序

    .net framework 2.0 版 Dictionary<string, string> collection = new Dictionary<string, string& ...

  6. QueryString to Dictionary<string, string>

    public class ModelConvertHelper<T> where T : new() {// 此处一定要加上new() public static IList<T&g ...

  7. Dictionary<string, object>

    Dictionary<string, object> dcic = JsonHelper.DataRowFromJSON(resultdepth); foreach (var depthk ...

  8. Dictionary<string, object>不区分大小写

    Dictionary<string, object> dic = new Dictionary<string, object>(StringComparer.OrdinalIg ...

  9. C#将URL中的参数转换成字典Dictionary<string, string>

    /// <summary> /// 将获取的formData存入字典数组 /// </summary> public static Dictionary<String, ...

随机推荐

  1. 烂泥:【解决】NFS服务器使用showmount –e命令报错

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 今天在NFS服务器使用showmount –e查看NFS共享目录时,发现系统一直显示如下错误: clnt_create: RPC: Port mappe ...

  2. yum或apt基本源设置指南

    关于: 管理Linux服务器的运维或开发人员经常需要安装软件,最常用方式应该是通过Linux系统提供的包管理工具来在线安装,比如centos的yum,ubuntu或debian的apt-get.当然这 ...

  3. 关于TreeView的选中事件

    在使用TreeView的选中事件时,发现,SelectAfter在第一次选中时触发,你再次点击时这个事件并不能引发它.所以找了找,发现有另两种解决办法. 最好的就是使用:NodeMouseClick, ...

  4. canvas作为背景

    比如canvas的id是HB, 画好后执行document.body.style.background = "url('"+HB.toDataURL()+"')" ...

  5. 修改/etc/profile文件

    通常情况下,/etc/profile文件是只读的,直接用vi或gedit打开修改后是无法保存的.要修改profile,需要取得root权限,(使用gedit编辑)应该如下: $sudo gedit / ...

  6. oracle函数--trunc

    作用:截取 语法:trunc(date,[fmt])   TRUNC函数,ORA-01898 精度说明符过多 TRUNC(SYSDATE)即可默认当前日期(年月日),---写到这一步就好了 TRUNC ...

  7. [转]C# 连接 Oracle 的几种方式

    本文转自:http://www.cnblogs.com/storys/archive/2013/03/06/2945914.html 一:通过System.Data.OracleClient(需要安装 ...

  8. PHP实现文件上传下载——心在忙而已

    这一周都没有写什么东西,是啊,一周时间都没有学习太多新的东西,除了开车. 妈蛋啊,天天中午去学车然后两周没有午觉的日子还是很崩溃的,加上之后工作压力带来的心忙,宝宝不开心啊. 不过,也是自己不是那么能 ...

  9. Java Web之Filter

    Filter被称为过滤器或者拦截器,基本功能就是对调用servler过程的拦截,在servlet进行响应和处理前后实现一些特殊功能.其实,Filter过滤器就是一个实现了javax.servlet.F ...

  10. cuda fft 计算

    #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h&g ...