一直对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. spring之依赖注入

  2. 烂泥:高负载均衡学习haproxy之TCP应用

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 在前几篇文章中,我们介绍了haproxy的配置参数,而且配置例子都是http协议(7层应用)的. 这篇文章,开始介绍haproxy的4层TCP应 ...

  3. 深入理解linux系统的目录结构(总结的非常详细)

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

  4. Android横竖屏切换重载问题与小结

    (转自:http://www.cnblogs.com/franksunny/p/3714442.html) (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com ...

  5. spring + redis 实现数据的缓存

    1.实现目标 通过redis缓存数据.(目的不是加快查询的速度,而是减少数据库的负担) 2.所需jar包 注意:jdies和commons-pool两个jar的版本是有对应关系的,注意引入jar包是要 ...

  6. 优化SQL查询:如何写出高性能SQL语句

    1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条 ...

  7. find 命令

    1.当前目录下查找"test.cpp"文件 find ./ -name test.cpp 2.当前查找含有"abcdef"字符串的文件 find ./ | xa ...

  8. 三:Go编程语言规范-表达式

    1.限定标识符 限定标识符为使用包名前缀限定的标识符.包名与标识符均不能为空白的.限定标识符用于访问另一个包中的标识符,它必须被导入. 标识符必须是已导出且在该包的包块中声明. math.Sin // ...

  9. No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案

    No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案 首先这个问题的产生是由于缺少Theme.App ...

  10. Nodejs 请求转发代理

    var sendPromise = function (res, callback) { var options = { hostname: settings.Ip, port: settings.P ...