.where(...).Any() 与 ..Any(...) 之间的性能差异 [重复]

Posted

技术标签:

【中文标题】.where(...).Any() 与 ..Any(...) 之间的性能差异 [重复]【英文标题】:Performance difference between .where(...).Any() vs ..Any(...) [duplicate] 【发布时间】:2019-09-16 05:09:27 【问题描述】:

可能重复:LINQ extension methods - Any() vs. Where() vs. Exists()

给定内存中的对象列表,我运行了以下两个表达式:

myList.where(x => x.Name == "bla").Any() 

对比

myList.Any(x => x.Name == "bla")

后者总是最快的,我相信这是由于 Where 枚举了所有项目。但是,当没有匹配项时也会发生这种情况。

我不确定确切的原因。是否存在这种被观察到的性能差异不会出现的情况,例如查询 Nhib?

干杯。

【问题讨论】:

您进行了哪些测试?多少次迭代?我们在这里谈论什么样的性能差异? 应该没什么区别。 ***.com/q/10110013/284240 快速更正:我怀疑您的意思是 == 而不是 = 投票结束。这个问题的答案提供了充足的见解 - ***.com/questions/3703256/… SearchQueryDTO 是一个具有名为 Name 的字符串属性的类。 IList myList = new List(); for (int i = 0; i x.Name == "499"); var time2 = timer2.Elapsed; //大约 0.5 毫秒 var timer = Stopwatch.StartNew(); var res = myList.Where(x => x.Name == "499").Any(); var time1 = timer.Elapsed; //大约 3.5 毫秒 【参考方案1】:

带有谓词的Any() 可以在没有迭代器的情况下执行其任务(yield return)。使用 Where() 会创建一个迭代器,这会增加对性能的影响(尽管非常小)。

因此,在性能方面(稍微),您最好使用带有谓词 (x => x.Name == "bla") 的 Any() 形式。就我个人而言,我觉得这也更具可读性......

附带说明,Where() 不一定枚举所有元素,它只是创建一个迭代器,在请求元素时遍历元素,因此在 Where() 之后对 Any() 的调用将驱动迭代,它将在找到与条件匹配的第一个项目处停止。

所以性能差异不是 Where() 迭代 所有 项目(在 linq-to-objects 中),因为它确实不需要(除非,当然,它没有找到满足它的),这是Where() 子句必须设置一个迭代器来遍历元素,而带有谓词的Any() 则没有。

【讨论】:

詹姆斯,谢谢你帮我解决这个问题!我运行了几次,总是得到这种性能差异。【参考方案2】:

假设您将where 更正为Where===,我希望“Any 带有谓词”版本的执行速度会稍微快一点。但是,我希望差异显着的情况很少而且相差甚远,因此您应该首先以可读性为目标。

碰巧,就可读性而言,我通常更喜欢“带有谓词的Any”版本,所以你在两个方面都赢了——但你真的应该首先选择你认为更具可读性的东西。 衡量在您真正关心的场景中的性能,如果某段代码没有按照您的需要执行,然后考虑对其进行微优化 - 每次都进行衡量步骤,当然。

【讨论】:

+1 表示 Any 有谓词,并注重可读性【参考方案3】:

我相信这是由于 Where 枚举了所有项目。

如果myList 是内存中的集合,则不是。 Where 方法使用延迟执行,因此它只会枚举所需数量的项目以确定结果。在这种情况下,您不会看到 .Any(...).Where(...).Any() 之间有任何显着差异。

在任何情况下,这种观察到的性能差异不会 是这样的,就像它在查询 Nhib 一样?

是的,如果 myList 是一个数据源,它将采用方法生成的表达式并转换为查询以在其他地方运行(例如 LINQ To SQL),您可能会看到不同之处。翻译表达式的代码在翻译其中一个表达式时做得更好。

【讨论】:

以上是关于.where(...).Any() 与 ..Any(...) 之间的性能差异 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用 .any() 后使用 np.where 返回错误 [重复]

实体框架 .Any 不生成预期的 SQL WHERE 子句

PostgreSQL:使用 LIKE、ANY 和通配符的 Where 子句

postgres:在 WHERE 子句中使用 CASE 和 ANY()

后续的变量声明必须具有相同的类型。变量“where”必须是“any[]”类型,但这里有“string[]”类型

Flutter 常用循环函数 forEach map where any every