网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计资源 > .Net编程 > 正文

项目经验总结(三)哪种方式查询泛型集合性能上最佳

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

  这篇文章我来分析下对于泛型集合,采取不同的查询方式在性能上会有什么样的影响?
    这里有一个城市简单信息的实体类:

  1. class CityInfo 
  2.     { 
  3.         public int CityID 
  4.         { 
  5.             get
  6.             set
  7.         } 
  8.         public string CityName 
  9.         { 
  10.             get
  11.             set
  12.         } 
  13.         public string CityNameEn 
  14.         { 
  15.             get
  16.             set
  17.         } 
  18.         public string CityAddress  
  19.         {  
  20.             get;  
  21.             set
  22.         } 
  23.     } 

我们构造一个特别大的城市泛型类:

  1. int i = 100000; 
  2. Random m = new Random(); 
  3. List<CityInfo> list = new List<CityInfo>(); 
  4. for (int j = 0; j < i; j++) 
  5.     CityInfo info = new CityInfo(); 
  6.     info.CityID = j; 
  7.     info.CityAddress = "aaaaaa" + j.ToString(); 
  8.     info.CityName = "城市中文名称" + j.ToString(); 
  9.     info.CityNameEn = "城市英文名称" + j.ToString(); 
  10.     list.Add(info); 

根据城市ID查询某个城市的具体信息:
     方法一:foreach:

  1. static CityInfo GetCityInfoByForeach(List<CityInfo> list, int CityID) 
  2.     CityInfo info = new CityInfo(); 
  3.     foreach (var item in list) 
  4.     { 
  5.         if (item.CityID == CityID) 
  6.         { 
  7.             info = item; 
  8.             breake; 
  9.         } 
  10.     } 
  11.     return info; 

方法二:for循环:

  1. static CityInfo GetCityInfoByFor(List<CityInfo> list, int CityID) 
  2.     CityInfo info = new CityInfo(); 
  3.     for (int i = 0; i < list.Count;i ++ ) 
  4.     { 
  5.         if (list[i].CityID == CityID) 
  6.         { 
  7.             info = list [i]; 
  8.             breake; 
  9.  
  10.          } 
  11.     } 
  12.     return info; 

  方法三:Linq查询:

  1. static CityInfo GetCityInfoByLinq(List<CityInfo> list,int CityID) 
  2.     CityInfo info = new CityInfo(); 
  3.     info = list.Where(p => p.CityID == CityID).FirstOrDefault(); 
  4.     return info; 

 然后随机产生一个城市ID,分别针对上面三种方式调用500次,这里何用老赵的CodeTimer来显示信息,执行结果如下:

  1. CodeTimer.Time("GetCityInfoByForeach", 500, () => GetCityInfoByForeach(list, m.Next(i - 1))); 
  2. CodeTimer.Time("GetCityInfoByFor", 500, () => GetCityInfoByFor(list, m.Next(i - 1))); 
  3. CodeTimer.Time("GetCityInfoByLinq", 500, () => GetCityInfoByLinq(list, m.Next(i - 1))); 

 性能从高到低表现为:for,foreach,linq,仔细查看三种方法生成IL代码,有一定的区别:

       1:foreach方法在查询数据时,依赖了Enumerator ,它的特点是不能像对于数组一样使用索引,而只能将当前项指针移动到集合的第一个或下一个元素,这是它性能不是最优的主要问题所在。在这种方式中还有一个重要点就是在查询每个元素时都会有try finally块,这也是需要消耗部分性能的。

  1. .try 
  2.  { 
  3.    IL_000d:  br.s       IL_0022 
  4.    IL_000f:  ldloca.s   CS$5$0000 
  5.    IL_0011:  call       instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<class ConsoleApplication1.CityInfo>::get_Current() 
  6.    IL_0016:  stloc.1 
  7.    IL_0017:  ldloc.1 
  8.    IL_0018:  callvirt   instance int32 ConsoleApplication1.CityInfo::get_CityID() 
  9.    IL_001d:  ldarg.1 
  10.    IL_001e:  bne.un.s   IL_0022 
  11.    IL_0020:  ldloc.1 
  12.    IL_0021:  stloc.0 
  13.    IL_0022:  ldloca.s   CS$5$0000 
  14.    IL_0024:  call       instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<class ConsoleApplication1.CityInfo>::MoveNext() 
  15.    IL_0029:  brtrue.s   IL_000f 
  16.    IL_002b:  leave.s    IL_003b 
  17.  }  // end .try 
  18.  finally 
  19.  { 
  20.    IL_002d:  ldloca.s   CS$5$0000 
  21.    IL_002f:  constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<class ConsoleApplication1.CityInfo> 
  22.    IL_0035:  callvirt   instance void [mscorlib]System.IDisposable::Dispose() 
  23.    IL_003a:  endfinally 
  24.  }  // end handler 

 2:for方法在查询数据时,System.Collections.Generic.List`1<class ConsoleApplication1.CityInfo>::get_Item(int32),比起foreach少了try的处理,最重要的是能够使用索引访问元素。
      3:linq方式性能最差。

      非常感谢各位朋友的指点,特别是代码中忘记加break,现在是修改代码后的测试结果:结果和上面一样。

总结:泛型集合如果数据量大,最好采用for循环查询,数据量少的话,用linq方式最佳,代码优雅且简洁。
      题外话:其实针对这种泛型集合查询,如果想优化性能,最好不要存储成泛型集合,采用Dictionary或者是hashtable效果更佳。

设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师