哪种方法执行得更好:.Any()vs.Count()>0?

哪种方法执行得更好:.Any()vs.Count()>0?

System.Linq命名空间,我们现在可以扩展IEnumerable就是拥有Any()Count() 可拓方法.

最近有人告诉我,如果我想检查一个集合中包含一个或多个项目,我应该使用.Any()扩展方法,而不是.Count() > 0方法,因为.Count()扩展方法必须遍历所有项。

第二,一些集合有一个财产(不是扩展方法)CountLength..是否最好使用这些,而不是.Any().Count() ?

是吗?


撒科打诨
浏览 899回答 3
3回答

呼如林

如果您是从具有.Length或.Count(如ICollection<T>,&nbsp;IList<T>,&nbsp;List<T>,等等)-那么这将是最快的选择,因为它不需要通过GetEnumerator()/MoveNext()/Dispose()所需序列Any()检查是否为非空的IEnumerable<T>顺序。只为IEnumerable<T>,然后Any()将要一般要更快,因为它只需要看一次迭代。但是,请注意,Count()检查ICollection<T>(使用.Count作为一种优化)-如果您的底层数据源是直接一个清单/集合,不会有太大的差别。别问我为什么它不使用非通用的ICollection...当然,如果您使用LINQ来过滤它,等等(Where(等等),您将有一个基于迭代器块的序列,因此ICollection<T>优化是无用的。一般IEnumerable<T>*坚持Any();-p

喵喔喔

当实体框架4是实际的时候,我写了这个答案。这个答案的目的不在于涉及琐碎的问题。.Any()VS.Count()性能测试。关键是要表明EF远非十全十美。新版本更好.。但是,如果您的代码部分速度慢,并且使用EF,则使用直接TSQL进行测试,并比较性能,而不是依赖于假设(即.Any()总是比.Count() > 0).虽然我同意大多数人投票通过的回答和评论-特别是在这一点上Any信号开发意图比Count() > 0-在SQLServer(EntityFramework4)上,计数按数量级计算得更快。下面是查询Any超时异常(在~200.000条记录上):con&nbsp;=&nbsp;db.Contacts. &nbsp;&nbsp;&nbsp;&nbsp;Where(a&nbsp;=>&nbsp;a.CompanyId&nbsp;==&nbsp;companyId&nbsp;&&&nbsp;a.ContactStatusId&nbsp;<=&nbsp;(int)&nbsp;Const.ContactStatusEnum.Reactivated &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&&&nbsp;!a.NewsletterLogs.Any(b&nbsp;=>&nbsp;b.NewsletterLogTypeId&nbsp;==&nbsp;(int)&nbsp;Const.NewsletterLogTypeEnum.Unsubscr) &nbsp;&nbsp;&nbsp;&nbsp;).OrderBy(a&nbsp;=>&nbsp;a.ContactId). &nbsp;&nbsp;&nbsp;&nbsp;Skip(position&nbsp;-&nbsp;1). &nbsp;&nbsp;&nbsp;&nbsp;Take(1).FirstOrDefault();Count版本以毫秒为单位执行:con&nbsp;=&nbsp;db.Contacts. &nbsp;&nbsp;&nbsp;&nbsp;Where(a&nbsp;=>&nbsp;a.CompanyId&nbsp;==&nbsp;companyId&nbsp;&&&nbsp;a.ContactStatusId&nbsp;<=&nbsp;(int)&nbsp;Const.ContactStatusEnum.Reactivated &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&&&nbsp;a.NewsletterLogs.Count(b&nbsp;=>&nbsp;b.NewsletterLogTypeId&nbsp;==&nbsp;(int)&nbsp;Const.NewsletterLogTypeEnum.Unsubscr)&nbsp;==&nbsp;0 &nbsp;&nbsp;&nbsp;&nbsp;).OrderBy(a&nbsp;=>&nbsp;a.ContactId). &nbsp;&nbsp;&nbsp;&nbsp;Skip(position&nbsp;-&nbsp;1). &nbsp;&nbsp;&nbsp;&nbsp;Take(1).FirstOrDefault();我需要找到一种方法来查看两个LINQ所产生的确切SQL-但很明显,两者之间的性能差别很大。Count和Any在某些情况下,不幸的是,你似乎不能就这样Any在任何情况下。编辑:这里是生成的SQL。如你所见;)ANY:exec&nbsp;sp_executesql&nbsp;N'SELECT&nbsp;TOP&nbsp;(1)&nbsp; [Project2].[ContactId]&nbsp;AS&nbsp;[ContactId],&nbsp; [Project2].[CompanyId]&nbsp;AS&nbsp;[CompanyId],&nbsp; [Project2].[ContactName]&nbsp;AS&nbsp;[ContactName],&nbsp; [Project2].[FullName]&nbsp;AS&nbsp;[FullName],&nbsp; [Project2].[ContactStatusId]&nbsp;AS&nbsp;[ContactStatusId],&nbsp; [Project2].[Created]&nbsp;AS&nbsp;[Created] FROM&nbsp;(&nbsp;SELECT&nbsp;[Project2].[ContactId]&nbsp;AS&nbsp;[ContactId],&nbsp;[Project2].[CompanyId]&nbsp;AS&nbsp;[CompanyId],&nbsp;[Project2].[ContactName]&nbsp;AS&nbsp;[ContactName], &nbsp;[Project2].[FullName]&nbsp;AS&nbsp;[FullName],&nbsp;[Project2].[ContactStatusId]&nbsp;AS&nbsp;[ContactStatusId],&nbsp;[Project2].[Created]&nbsp;AS&nbsp;[Created],&nbsp;row_number()&nbsp; &nbsp;OVER&nbsp;(ORDER&nbsp;BY&nbsp;[Project2].[ContactId]&nbsp;ASC)&nbsp;AS&nbsp;[row_number] &nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;(&nbsp;SELECT&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[ContactId]&nbsp;AS&nbsp;[ContactId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[CompanyId]&nbsp;AS&nbsp;[CompanyId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[ContactName]&nbsp;AS&nbsp;[ContactName],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[FullName]&nbsp;AS&nbsp;[FullName],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[ContactStatusId]&nbsp;AS&nbsp;[ContactStatusId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[Created]&nbsp;AS&nbsp;[Created] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;[dbo].[Contact]&nbsp;AS&nbsp;[Extent1] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WHERE&nbsp;([Extent1].[CompanyId]&nbsp;=&nbsp;@p__linq__0)&nbsp;AND&nbsp;([Extent1].[ContactStatusId]&nbsp;<=&nbsp;3)&nbsp;AND&nbsp;(&nbsp;NOT&nbsp;EXISTS&nbsp;(SELECT&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;AS&nbsp;[C1] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;[dbo].[NewsletterLog]&nbsp;AS&nbsp;[Extent2] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WHERE&nbsp;([Extent1].[ContactId]&nbsp;=&nbsp;[Extent2].[ContactId])&nbsp;AND&nbsp;(6&nbsp;=&nbsp;[Extent2].[NewsletterLogTypeId]) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)) &nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;&nbsp;AS&nbsp;[Project2] )&nbsp;&nbsp;AS&nbsp;[Project2] WHERE&nbsp;[Project2].[row_number]&nbsp;>&nbsp;99 ORDER&nbsp;BY&nbsp;[Project2].[ContactId]&nbsp;ASC',N'@p__linq__0&nbsp;int',@p__linq__0=4COUNT:exec&nbsp;sp_executesql&nbsp;N'SELECT&nbsp;TOP&nbsp;(1)&nbsp; [Project2].[ContactId]&nbsp;AS&nbsp;[ContactId],&nbsp; [Project2].[CompanyId]&nbsp;AS&nbsp;[CompanyId],&nbsp; [Project2].[ContactName]&nbsp;AS&nbsp;[ContactName],&nbsp; [Project2].[FullName]&nbsp;AS&nbsp;[FullName],&nbsp; [Project2].[ContactStatusId]&nbsp;AS&nbsp;[ContactStatusId],&nbsp; [Project2].[Created]&nbsp;AS&nbsp;[Created] FROM&nbsp;(&nbsp;SELECT&nbsp;[Project2].[ContactId]&nbsp;AS&nbsp;[ContactId],&nbsp;[Project2].[CompanyId]&nbsp;AS&nbsp;[CompanyId],&nbsp;[Project2].[ContactName]&nbsp;AS&nbsp;[ContactName], &nbsp;[Project2].[FullName]&nbsp;AS&nbsp;[FullName],&nbsp;[Project2].[ContactStatusId]&nbsp;AS&nbsp;[ContactStatusId],&nbsp;[Project2].[Created]&nbsp;AS&nbsp;[Created], &nbsp;&nbsp;row_number()&nbsp;OVER&nbsp;(ORDER&nbsp;BY&nbsp;[Project2].[ContactId]&nbsp;ASC)&nbsp;AS&nbsp;[row_number] &nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;(&nbsp;SELECT&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Project1].[ContactId]&nbsp;AS&nbsp;[ContactId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Project1].[CompanyId]&nbsp;AS&nbsp;[CompanyId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Project1].[ContactName]&nbsp;AS&nbsp;[ContactName],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Project1].[FullName]&nbsp;AS&nbsp;[FullName],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Project1].[ContactStatusId]&nbsp;AS&nbsp;[ContactStatusId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Project1].[Created]&nbsp;AS&nbsp;[Created] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;(&nbsp;SELECT&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[ContactId]&nbsp;AS&nbsp;[ContactId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[CompanyId]&nbsp;AS&nbsp;[CompanyId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[ContactName]&nbsp;AS&nbsp;[ContactName],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[FullName]&nbsp;AS&nbsp;[FullName],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[ContactStatusId]&nbsp;AS&nbsp;[ContactStatusId],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Extent1].[Created]&nbsp;AS&nbsp;[Created],&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(SELECT&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COUNT(1)&nbsp;AS&nbsp;[A1] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;[dbo].[NewsletterLog]&nbsp;AS&nbsp;[Extent2] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WHERE&nbsp;([Extent1].[ContactId]&nbsp;=&nbsp;[Extent2].[ContactId])&nbsp;AND&nbsp;(6&nbsp;=&nbsp;[Extent2].[NewsletterLogTypeId]))&nbsp;AS&nbsp;[C1] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FROM&nbsp;[dbo].[Contact]&nbsp;AS&nbsp;[Extent1] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;&nbsp;AS&nbsp;[Project1] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WHERE&nbsp;([Project1].[CompanyId]&nbsp;=&nbsp;@p__linq__0)&nbsp;AND&nbsp;([Project1].[ContactStatusId]&nbsp;<=&nbsp;3)&nbsp;AND&nbsp;(0&nbsp;=&nbsp;[Project1].[C1]) &nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;&nbsp;AS&nbsp;[Project2] )&nbsp;&nbsp;AS&nbsp;[Project2] WHERE&nbsp;[Project2].[row_number]&nbsp;>&nbsp;99 ORDER&nbsp;BY&nbsp;[Project2].[ContactId]&nbsp;ASC',N'@p__linq__0&nbsp;int',@p__linq__0=4似乎纯粹的Where With比计算Count然后使用count=0执行WHERE要糟糕得多。如果你们看到我的发现有什么错误请告诉我。不管对VS计数的讨论如何,都可以从这一切中删除任何更复杂的LINQ,当将其重写为存储过程时,情况要好得多;)。
打开App,查看更多内容
随时随地看视频慕课网APP