C#:判断集合非空Any一定比Count好?

本文通过实验对比了LINQ中Any与Count方法在不同场景下的性能表现,揭示了两者在.NET Framework内置集合与不确定长度的IEnumerable<T>上的实际运行效率差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:http://blog.csdn.NET/caesarliu1121/article/details/24775249


现在网上谈到Linq中的判断集合非空基本都说要用Any比Count好. 但真实情况是这样的吗?

 

首先我们要从AnyCount的差别说起.Any() 使用IEnumerator.GetEnumerator() 和 MoveNext() 來判断是否集合为空,而Count()则是返回整个集合的元素个数.  就像网上大多数文章所说的Count() > 0 遇上 yeild return必定会出现性能问题。因为当遇到使用 yield return 返回集合的方法時,如果使用了 Count() 的話,就相当于遍历一遍整个集合然后得到集合个数。最典型的就是LINQ to SQL等对外部数据进行Linq操作.

 

 并且网上还有说法称Any.Net内建的集合类型上会退化成Count.这样看来貌似Any是比Count更好的一个选择.但Caesar我从反编译的.Net代码来看好像不是这样.是我有什么地方遗漏了吗?我决定直接测试一下.


[csharp]  view plain  copy  在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Diagnostics;  
  4. using System.Linq;  
  5. using System.Text;  
  6. using System.Threading.Tasks;  
  7.   
  8. namespace TestSharp  
  9. {  
  10.     class Program  
  11.     {  
  12.         static void Main(string[] args)  
  13.         {  
  14.             var li = new List<int> {1, 2, 3};  
  15.             // 预热一下  
  16.             CheckByAny(li, 1);  
  17.             CheckByCount(li, 1);  
  18.               
  19.             int number = 1000000;  
  20.             CheckByAny(li, number);  
  21.             CheckByCount(li, number);  
  22.   
  23.             Console.ReadLine();  
  24.         }  
  25.   
  26.         private static long CheckByCount(List<int> li, int num)  
  27.         {  
  28.             var wa = new Stopwatch();  
  29.             wa.Start();  
  30.             for (int i = 0; i < num; ++i)  
  31.             {  
  32.                 if (li.Count() < 0)  
  33.                     break;  
  34.             }  
  35.             wa.Stop();  
  36.             Console.WriteLine("count: " + wa.ElapsedTicks);  
  37.             return wa.ElapsedTicks;  
  38.         }  
  39.   
  40.         private static long CheckByAny(List<int> li, int num)  
  41.         {  
  42.             var wa = new Stopwatch();  
  43.             wa.Start();  
  44.             for (int i = 0; i < num; ++i)  
  45.             {  
  46.                 if (li.Any() == false)  
  47.                     break;  
  48.             }  
  49.             wa.Stop();  
  50.             Console.WriteLine("any: " + wa.ElapsedTicks);  
  51.             return wa.ElapsedTicks;  
  52.         }  
  53.     }  
  54. }  

通过多次的测试, Any函数所花的时间基本是Count函数的两倍多.

其中一次的结果如下.

Any: 151462

Count: 60816


当然这个测试还比较简单. 最好是用上老赵的性能计数器.(http://www.cnblogs.com/JeffreyZhao/archive/2009/03/10/codetimer.html)


那为什么Any()会比Count()慢呢? 原因也很简单.因为Any() 需要GetEnumerator() / MoveNext() / Dispose() ,虽然只有一次,但也是要花资源的。而对内建类型 Count()基本就是一个读取操作.

结论:

  • 集合是來自不确定个数的IEnumerable<T>使用 Any().
  • 集合是來自外部数据 (ex: LINQto SQL, LINQ to Entities) 使用 Any().
  • 集合是來自 .NET Framework 內建的集合请使用 Count() .
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值