一直对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. MySQL入门(三)

    写了两篇<MySQL入门>以后我发现,写书的人还是都挺有本事的,起码人家知道怎么编排自己想讲的知识点,我实在是不知道该先说那里后说哪里,那我就想到什么讲什么吧. 一 写SQL 其实我是不想 ...

  2. javax.servlet.ServletException cannot be resolved to a type错误解决方法

    在页面中使用全局路径时${pageContext.request.contextPath}出现javax.servlet.ServletException cannot be resolved to ...

  3. 几种语言的CGI编程

    为了了解PHP.JSP.ASP出现之前人们写网站的方法,洒家研究了一波CGI,使用C.Python.batch.shell script语言写了几个简单的网页. CGI即通用网关接口,指web服务器调 ...

  4. DirectX API 编程起步 #01 项目设置

    =========================================================== 目录: DirectX API 编程起步 #02 窗口的诞生 DirectX A ...

  5. 【2016-10-15】【坚持学习】【Day6】【组合模式】

    哈哈,今天偷懒了,在晚上只看了一个组合模式. 例子: 树结构,有一些是树节点,一些是叶子节点. 比如,文件夹树结构,一个是文件夹节点,一个是文件节点,虽然都是树的节点,但是具体的业务肯定是区别的. 代 ...

  6. Jetty使用攻略

    jetty作为一款小型的web容器用处很大,因为其小巧强大,经常作为嵌入式的组件处理http交互. Jetty 作为一个独立的 Servlet 引擎可以独立提供 Web 服务,但是它也可以与其他 We ...

  7. UVALive 5066 Fire Drill --BFS+DP

    题意:有一个三维的地图,有n个人被困住,现在消防队员只能从1楼的一个入口进入,营救被困者,每一个被困者有一个价值,当消防队员找到一个被困者之后,他可以营救或者见死不救,如果救的话,他必须马上将其背到入 ...

  8. BZOJ2763[JLOI2011]飞行路线 [分层图最短路]

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2523  Solved: 946[Submit][Statu ...

  9. NOIP2012pj文化之旅[floyd]

    描述 有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次,即如果他学习了某种文化,则他就不能到达其他有这种文化的国家.不同的国家可能有相同的文化.不同文化的国家 ...

  10. 当手机被PS掉,人们看到的是手中的灵魂

    Eric Pickersgill是一名摄影师,最近喜欢拍摄并记录人们使用智能手机的情景,不过不同的是,在最终作品中会将手机从人们手中PS掉,一刹那会进入一个奇怪的世界.黑白照片也极具冲击力. 每个人神 ...