原文(http://www.cnblogs.com/ldp615/archive/2011/12/11/2284154.html)

Linq 出现之前,我们通常使用下面的方式来判断集合是否非空,即集合包含元素:

 var array = new int[];
var b1 = array.Length > ; var list = new List<string>();
var b2 = list.Count > ; var collection = new Collection<double>();
var b3 = collection.Count > ;

使用 Length 或 Count 属性,上面的写法没有问题。

但到了 Linq 时代,Enumerable.Count 扩展方法“统一了“ Length 和 Count 属性,于是就有了下面判断非空的写法:

 public static void SomeAction<T>(IEnumerable<T> source){
if (source.Count() > ){
//...
}//...
}

这种写法可以,运行也正常,但可能会产生非常严重的性能的问题

注意是可能,并不是一定,上面的方法如果传入的是 Array、List<T>或Collection<T>,不会有问题。

那么什么时候会出问题呢?我们来看如下方法:

public static IEnumerable<int> GetNums(int start, int count)
{
var end = start + count;
for (int i = start; i < end; i++)
yield return i;
}

  如下调用时:

var nums = GetNums(, int.MaxValue);
SomeAction(nums);

执行速度会相当慢,我的电脑大约用了 70 秒的时间来执行 source.Count() > 0。

分析下的话,你会发现 GetNums 第 5 行代码 yield return i 执行了 int.MaxValue 次,有必要吗?

其实只要返回一个元素我们就可以断定集合非空,完全不需要将所有的元素返回。

那又如何来判断呢?我们可以使用 Enumerable.Any 扩展方法:

将 SomeAction 方法修改如下:

public static void SomeAction<T>(IEnumerable<T> source){
if(source.Any()){ // 切勿使用 source.Count() > 0
//...
}//...
}

再次调用 ,你会发现执行时间可以忽略不计了。

总结下规律, Count() > 0 遇上 yeild return 必定会出现性能问题

Enumerable.Any 扩展方法可以解决我们的问题,但这个方法在命名上似乎有些问题,总感觉有点不顺,如若判断集合为空:

if (!source.Any()) { //...
}

! source.Any() 更显得绕口,我们可以新增两个扩展方法 IsEmpty、IsNotEmpty 来解决,请参考:

c# 扩展方法奇思妙用基础篇十:IsEmpty、IsNotEmpty 扩展

Linq:切勿使用 Count() > 0 来判断集合非空的更多相关文章

  1. 用Count() > 0 来判断集合非空的问题

    Linq 出现之前,我们通常使用下面的方式来判断集合是否非空,即集合包含元素: ]; ; var list = new List<string>(); ; var collection = ...

  2. mysql 5.7中 count(0) count(*) count(主键) count(非空字段)效率比较

    mysql count(0) count(*) count(主键) count(非空字段) 效率比较 写代码的时候经理在背后说了一句count(0)的效率高于count(*) ,索性全部测试了一下 结 ...

  3. LINQ体验(2)——C# 3.0新语言特性和改进(上篇)

    整体来说.Visual Studio 2008和.NET 3.5是建立在.NET2.0核心的基础之上,.NET2.0核心本身将不再变化(假设不了解.NET2.0的朋友,请參看MSDN或者一些经典的书籍 ...

  4. org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

    org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actua ...

  5. Oracle > count(*) / count(0) / count(1) | order by 1, 2

    select count(*), select count(0), select count(1) from table 在统计表的行数时候,经常用到 select count(*) 然而对于行数很多 ...

  6. 20.org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

    org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actua ...

  7. 关于Hibernate级联更新插入信息时提示主键不为空的问题“org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1 ”

    org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual ...

  8. 关于Error during managed flush [Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1]错误

    控制台报错: 08:07:09.293 [http-bio-8080-exec-2] ERROR org.hibernate.internal.SessionImpl - HHH000346: Err ...

  9. Select count(*)、Count(1)、Count(0)的区别和执行效率比较

    记得很早以前就有人跟我说过,在使用count的时候要用count(1)而不要用count(*),因为使用count(*)的时候会对所有的列进行扫描,相比而言count(1)不用扫描所有列,所以coun ...

随机推荐

  1. Sqlserver统计语句

    --查看被缓存的查询计划 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED st.text AS [SQL] , cp.cacheobjtype , c ...

  2. asp net 编程问题 实现下一篇 和上一篇效果

    首先是access数据库,有一个名为news的表,里面有三个字段,分别为id,classid 和name 其中id为主键,classid可以重复 现在有以下数据: id classid name 1 ...

  3. The Definitive C++ Book Guide and List

    学习c++的书单 转自 http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list Beginner ...

  4. mfc EDIT字体颜色

    改变Edit字体颜色: 1.CMyDlg类中添加成员变量: CBrush m_Brush; 2.OnInitDialog中初进行设置: m_brush.CreateSolidBrush(RGB(0,2 ...

  5. Nutch的日志系统

    一.Nutch日志实现方式 1.Nutch使用slf4j作为日志接口,使用log4j作为具体实现.关于二者的基础,请参考 http://blog.csdn.net/jediael_lu/article ...

  6. [转]hibernate主键生成策略

    1.自动增长identity 适用于MySQL.DB2.MS SQL Server,采用数据库生成的主键,用于为long.short.int类型生成唯一标识使用SQL Server 和 MySQL 的 ...

  7. iOS学习之视图加载过程中会触发的方法(loadView/viewDidLoad/didReceiveMemoryWarning)

    1.loadView 这是视图控制器用来加载根视图的方法; 如果需要将自定义的视图作为根视图,则不需要调用父类对该方法的实现([super loadView]);直接将自定义视图通过self.view ...

  8. editor.md实现Markdown编辑器

    editor.md实现Markdown编辑器 Markdown和Editor.md简介 Markdwon编辑器在技术工作者圈子中已经越来越流行,简单的语法,统一的格式,强大的扩展功能,最重要的是:你可 ...

  9. sgu To xor or not to xor

    题意:从n个数中,选择一些数,使得异或最大. #include <cstdio> #include <cstring> #include <algorithm> # ...

  10. DJANGO的HTTPRESPONSE流式输出

    在项目当中遇到的问题,网上有样例代码,但都不行,后来,发现在了1.5版本之后,新的STREAMHTTPRESPONSE对象, 搞定. from django.http import HttpRespo ...