一直对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. java.lang.NoClassDefFoundError:TagSupport

    这个错误应该就是没有成功加载tomcat自带的jar包jsp-api.jar. 在网上看到很多网友说要把tomcat/lib下的jsp-api.jar拷贝到项目/WEB_INF/lib下并导入,本人试 ...

  2. 烂泥:nginx同时支持asp.net与php

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 经过两天的实验,终于让nginx同时支持asp.net与php了.下面就把具体的配置过程记录如下. 注意:本次实验OS:centos6 64bit. 尽 ...

  3. jsp html5 video实现在线视频播放源码,支持IE6,7,8,10,11,谷歌,火狐等浏览器

    jsp源码: <%@ page language="java" import="java.util.*" pageEncoding="utf-8 ...

  4. 工作中常用的Linux命令:ipcs/ipcrm命令

    本文链接:http://www.cnblogs.com/MartinChentf/p/6057100.html (转载请注明出处) ipcs 1. 命令格式 ipcs [resource-option ...

  5. android 判断字符串是否为空与比对["=="与equals()的区别]

    if (s == null || s.equals("")) ; } s.equals("")里面是要比对的字符串 声明字符串未赋初始值或值,然后比对就会出错, ...

  6. @Value取不到值引出的spring的2种配置文件applicationContext.xml和xxx-servlet.xml

    项目中经常会用到配置文件,定义成properties的形式比较常见,为了方便使用一般在spring配置文件中做如下配置: <context:property-placeholder ignore ...

  7. js对已经对象类型进行类型辨别

    typeof() Object.prototype.toString.call(data)

  8. 新手必学的java报表开发工具FineReport实用技巧

    1.在制作模板时,如何将报表中的值传递到超链接网页呢? 在项目中以frame方法把F1.CPT放到项目的页面中,对F1.CPT做网络报表超链接F2.CPT,然后在F2.cpt页面中,做个超链接的网页, ...

  9. 准备使用 Office 365 中国版--安装

    温故而知新,先附上一个链接:Office 365常见问题 Office 365中Office套件的安装介质和传统Office套件的安装介质是有些区别的,虽然功能都一样.因此,如果购买了带Office套 ...

  10. Caffe 抽取CNN网络特征 Python

    Caffe Python特征抽取 转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ Caffe大家一般用到的深度学 ...