LINQ中那些你所不知道的秘密

  一直对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条件也十分通俗易懂。但是当你需要频繁检索某个集合中的满足某些条件的对象时,比如需要求两个集合中的差集时,你有没有考虑过性能问题呢?最近的项目遇到频繁检索资料库,对比查询的多个对象的性能瓶颈问题,于是做了下面这个测试,下面我们来看一个对比测试:

 1  public static class LinqOrDictioanry
 2     {
 3         public static string GetLinqSingle(List<Model> model, string id, string sbName)
 4         {
 5             return model.Single(o => o.Id == id && o.SbName == sbName).JuName;
 6         }
 7         public static string GetDictionaryValue(Dictionary<string, Model> dictionaryModel, string id, string sbName)
 8         {
 9             return dictionaryModel[string.Format("{0}\t{1}", id, sbName)].JuName;
10         }
11     }

 1  [TestMethod]
 2         public void TestMethod1()
 3         {
 4             var model = new List<Model>();
 5             const int count = 100000;
 6             var time = 3;
 7             var random = new Random(count);
 8             for (var i = 0; i < count; i++)
 9             {
10                 model.Add(new Model()
11                 {
12                     Id = Guid.NewGuid().ToString(),
13                     JuName = "JuName" + random.Next(0, 10000),
14                     SbName = "SbName" + random.Next(0, 10000),
15                     Dydj = "Dydj" + random.Next(0, 10000),
16                     ZhangChang = "ZhangChang" + random.Next(0, 10000),
17                     YcHang = "YcHang" + random.Next(0, 10000),
18                     Time = DateTime.Now,
19                     Total = random.Next(0, 10000)
20                 });
21             }
22             var dictionary = model.ToDictionary(d => string.Format("{0}\t{1}", d.Id, d.SbName), d => d);
23
24             var toModel = new List<Model>();
25             var tempCount = random.Next(500, 10000);
26             for (var i = 0; i < tempCount; i++)
27             {
28                 var sample = model[random.Next(model.Count)];
29                 toModel.Add(new Model()
30                 {
31                     Id = sample.Id,
32                     SbName = sample.SbName
33                 });
34             }
35             Console.WriteLine("Count={0}>{1}", model.Count, tempCount);
36             for (var i = 0; i < time; i++)
37             {
38                 Console.WriteLine("第 {0}次检索{1} 个对象", i, tempCount);
39                 var sw = new Stopwatch();
40                 sw.Start();
41                 for (var j = 0; j < tempCount; j++)
42                 {
43                     var model1 = toModel[j];
44                     model1.JuName = LinqOrDictioanry.GetLinqSingle(model, model1.Id, model1.SbName);
45                 }
46                 sw.Stop();
47                 Console.WriteLine("耗时 {0}ms", sw.ElapsedMilliseconds);
48                 Console.WriteLine("查看目标集合中最前面的数据,中间一点的数据,和最后一个数据看是否成功把数据检索出来?{0}, {1}, {2}", toModel[1].JuName, toModel[tempCount / 2].JuName, toModel[tempCount - 1].JuName);
49             }
50             Console.WriteLine("");
51             for (var i = 0; i < time; i++)
52             {
53                 Console.WriteLine("第 {0}次检索{1}个对象", i, tempCount);
54                 var sw = new Stopwatch();
55                 sw.Start();
56                 for (var j = 0; j < tempCount; j++)
57                 {
58                     var model1 = toModel[j];
59                     model1.JuName = LinqOrDictioanry.GetDictionaryValue(dictionary, model1.Id, model1.SbName);
60                 }
61                 sw.Stop();
62                 Console.WriteLine("耗时 {0}ms", sw.ElapsedMilliseconds);
63                 Console.WriteLine("查看目标集合中最前面的数据,中间一点的数据,和最后一个数据看是否成功把数据检索出来?{0} ,{1} ,{2}", toModel[1].JuName, toModel[tempCount / 2].JuName, toModel[tempCount - 1].JuName);
64             }
65         }

  随机构造一个容量为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,可以获得大幅度的性能提升。

  鄙人能力有限,以上测试纯属个人知识点查缺补漏应用,不敢强加应用场景,以免误人子弟,若有不妥或者错误的地方,还望各位大神斧正。

时间: 2024-08-02 11:03:20

LINQ中那些你所不知道的秘密的相关文章

唐卡定制之你所不知道的秘密

唐卡定制之你所不知道的秘密 唐卡定制的目的涉及到了他独特的艺术特色,蕴藏着藏族艺术的神秘色彩,历史底蕴肥厚,是很多重大历史事件和政治事件的有力史据.最近流行的唐卡收藏热又将唐卡定制推到了一个巅峰,唐卡的技法逐渐精湛细致也促进了唐卡定制的发展. 唐卡的收藏是极其难的,只有充分的了解了藏族文化的发展,才能使它的收藏具有更多的文化价值.西藏的唐卡绘画难懂,有很浓重的历史韵味,画风也多变,一般的收藏者很难全部弄懂其中的因因果果,在收藏上往往难以下手.唐卡大多数都是描绘佛教盛世的作品,佛教专用型很强,因此

移动游戏开发,你所不知道的秘密!

<2014 年中国游戏产业报告>.报告显示,截止2014年底,中国游戏市场用户数量约达到 5.17 亿人,比 2013 年增长了4.6%. 中国游戏市场(包括网络游戏市场.移动游戏市场.单机游戏市场等) 实际销售收入达到1144.8亿元人民币(Newzoo统计的2014年中国游戏收入为17,866,677,000美元),比 2013 年增长了 37.7%. 在中国游戏市场实际销售收入中,客户端网络游戏市场占有率达到 53.19%,网页游戏市场占有率达到 17.7%,移动游戏市场为 24.01%

电脑键盘上你所不知道的秘密,学会了很牛气!

1.很多时候,需要暂时离开座位去做别的事情,如果对自己的电脑安全很重视,不妨按住windows键后,再按L键,这样电脑就直接锁屏了,这样就不用担心电脑的资料外泄啦 2.要找电脑上的文件时,一般人会先找到“我的电脑”,然后点击打开,而高手总是很酷的,轻轻按下键盘上的Windows键不放然后再按E键,直接打开电脑的资源管理器,而一般人还在慢慢寻找“我的电脑”的图标呢,嗯,高手就是这样直接把一般人给秒杀了的 3. 正在玩游戏或看羞羞的东西的时候,Boss进来了!鼠标一下子点不到右下角的显示桌面,怎么办

关于汽车轮胎?你所不知道的秘密

汽车轮胎属于车辆的安全件,很多客户对汽车轮胎的日常维护及汽车轮胎的保养了解不充分. 为此,开新就为大家讲解一下关于轮胎轮毂的一些常识. 胎压,这个是很有说法的,不仅能够节省油耗,还保证了车辆的安全驾驶!一般轿车上轮胎都有胎压指定规格,可以按照这上面的参数来进行胎压的设定.切记,车辆行驶一段路程后莫要测量胎压,因为这时的胎压都偏高,车辆行驶十分钟以上轮胎与地面摩擦导致胎内温度上升,胎压随之上升. 轮胎自然磨损的时间在上海路况来看,以二年为期限,行驶二年的轮胎得查看是否需要更换了.超过二年的轮胎,会

你所不知道的html5与html中的那些事(二)

文章简介: 关于html5相信大家早已经耳熟能详,但是他真正的意义在具体的开发中会有什么作用呢?相对于html,他又有怎样的新的定义与新理念在里面呢?为什么一些专家认为html5完全完成后,所有的工作都可以达到真正的云方式呢?这一系列的问题你是否已经想明白了呢? 本系列文章将为您一一解答你所不知道的关于html5与html中的那些事;具体会包括如:html5新的理念与想法,html5的新标签的用意与具体开发中场景应用,html5与css3的感情经历(用法搭配),包括html5的父亲html的一些

你所不知道的html5与html中的那些事(一)

分类: Web开发 文章简介: 关于html5相信大家早已经耳熟能详,但是他真正的意义在具体的开发中会有什么作用呢?相对于html,他又有怎样的新的定义与新理念在里面呢?为什么一些专家认为html5完全完成后,所有的工作都可以达到真正的云方式呢?这一系列的问题你是否已经想明白了呢? 本系列文章将为您一一解答你所不知道的关于html5与html中的那些事;具体会包括如:html5新的理念与想法,html5的新标签的用意与具体开发中场景应用,html5与css3的感情经历(用法搭配),包括html5

你所不知道的html5与html中的那些事(四)——文本标签

文章简介: 关于html5相信大家早已经耳熟能详,但是他真正的意义在具体的开发中会有什么作用呢?相对于html,他又有怎样的新的定义与新理念在里面呢?为什么一些专家认为html5完全完成后,所有的工作都可以达到真正的云方式呢?这一系列的问题你是否已经想明白了呢? 本系列文章将为您一一解答你所不知道的关于html5与html中的那些事;具体会包括如:html5新的理念与想法,html5的新标签的用意与具体开发中场景应用,html5与css3的感情经历(用法搭配),包括html5的父亲html的一些

你所不知道的html5与html中的那些事(三)

文章简介: 关于html5相信大家早已经耳熟能详,但是他真正的意义在具体的开发中会有什么作用呢?相对于html,他又有怎样的新的定义与新理念在里面呢?为什么一些专家认为html5完全完成后,所有的工作都可以达到真正的云方式呢?这一系列的问题你是否已经想明白了呢? 本系列文章将为您一一解答你所不知道的关于html5与html中的那些事;具体会包括如:html5新的理念与想法,html5的新标签的用意与具体开发中场景应用,html5与css3的感情经历(用法搭配),包括html5的父亲html的一些

Android中Context详解 ---- 你所不知道的Context

转载至 :http://blog.csdn.net/qinjuning 前言:本文是我读<Android内核剖析>第7章 后形成的读书笔记 ,在此向欲了解Android框架的书籍推荐此书. 大家好,  今天给大家介绍下我们在应用开发中最熟悉而陌生的朋友-----Context类 ,说它熟悉,是应为我们在开发中 时刻的在与它打交道,例如:Service.BroadcastReceiver.Activity等都会利用到Context的相关方法 : 说它陌生,完全是 因为我们真正的不懂Context