一直对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. 优化SQLServer——表和分区索引(二)

    简介     之前一篇简单的介绍了语法和一些基本的概念,隔了一段时间,觉得有必要细致的通过实例来总结一下这部分内容.如之前所说,分区就是讲大型的对象(表)分成更小的块来管理,基本单位是行.这也就产生了 ...

  2. jquery checkbox操作

    一.通过选择器选取CheckBox: 1.给CheckBox设置一个id属性,通过id选择器选取: <input type="checkbox" name="myB ...

  3. 简易的GCC图形界面GCCUI

    这个 GCCUI.EXE 是配合上一篇博文<用VC6开发嵌入式LINUX程序>说的:用VC6辅助开发LINUX程序的时候使用.把 gcc 编译器增加一个简易的图形界面,可以自动读取 vc6 ...

  4. android 读取根目录下的文件或文件夹

    @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setC ...

  5. 天朝使用GAE入门指南

    0. 引言 Across the Great Wall, we can reach every corner in the world. 洒家最近玩了几下 Google App Engine.由于众所 ...

  6. ViewPager+Fragment再探:和TAB滑动条一起三者结合

    Fragment前篇: <Android Fragment初探:静态Fragment组成Activity> ViewPager前篇: <Android ViewPager初探:让页面 ...

  7. 小菜学Chromium之OpenGL学习之二

    在这个教程里,我们一起来玩第一个OpenGL程序.它将显示一个空的OpenGL窗口,可以在窗口和全屏模式下切换,按ESC退出.它是我们以后应用程序的框架. 在CodeBlock里创建一个新的GLUT ...

  8. 【转帖】4412ARM开发板学习笔记(一)

    本文转自迅为论坛:http://www.topeetboard.com 新手在进行开发学习前,建议先看01-迅为电子开发板入门视频.对开发板和开发环境有一定的了解后,不要盲目接线开机.以下是个人的一点 ...

  9. [转]C#网络编程(同步传输字符串) - Part.2

    本文转自:http://www.tracefact.net/CSharp-Programming/Network-Programming-Part2.aspx 服务端客户端通信 在与服务端的连接建立以 ...

  10. 翻译《Writing Idiomatic Python》(四):字典、集合、元组

    原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...