c# - Linq 性能 : does it make sense to move out condition from query?

标签 c# .net performance linq linq-to-objects

有一个 LINQ 查询:

int criteria = GetCriteria();
var teams = Team.GetTeams()
    .Where(team=> criteria == 0 || team.Criteria == criteria)
    .ToList();

从性能(或任何其他角度)将其转换为以下是否有意义?

var teams = Team.GetTeams();
if (criteria != 0)
{
    teams = teams.Where(team => team.Criteria == criteria);
}
teams = teams.ToList();

我有一套可靠的标准;我应该将它们分开并仅在必要时应用每个标准吗?或者只是将它们应用到一个 LINQ 查询中,然后让 .NET 来优化查询?

请指教。欢迎任何想法!

附言伙计们,我不使用 Linq2Sql,只使用 LINQ,那是纯 C# 代码

最佳答案

首先,重要的是要了解 LINQ 实际上有几种变体,主要可以根据它们是使用表达式树还是编译代码来执行查询来划分。

Linq2Sql(以及任何将查询转换为另一种形式以执行查询的 Linq 提供程序)使用表达式树,以便可以分析查询并将其转换为另一种形式(通常是 SQL)。在这种情况下,提供者可以修改查询,潜在地执行某种程度的优化。我不知道目前有任何供应商这样做。

Linq to Objects 使用编译后的代码,并且将始终按编写的方式执行查询。除了开发人员之外,没有机会优化查询。

其次,所有 Linq 查询都是延迟的。这意味着在尝试获取结果之前,查询不会真正执行。这样做的副作用是您可以分几步构建查询,并且只会执行最终查询。问题中的第二个示例仍然导致仅执行一个查询

如果您使用的是 Linq2Sql,那么这两个查询可能具有大致相似的性能。然而,扩展到处理许多标准的第一个示例可能会导致糟糕的过于通用的执行计划,最终会降低性能。修剪后的查询不存在这种风险,并且将为每个真实的条件排列生成一个执行计划。

如果您使用 Linq to Objects,那么第二个查询绝对更可取,因为第一个查询将为每个输入执行一次传递给 Where 的谓词,即使条件始终返回 true。

关于c# - Linq 性能 : does it make sense to move out condition from query?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10274984/

相关文章:

c# - ScriptIgnore 导致其他属性,例如 StringLength 被忽略

.net - 找不到库 hostpolicy.dll

服务器端渲染上的 PHP 和 React

java - 特定类型会影响 ArrayList 的性能吗?

c# - 如何使用 .NET SqlDependency 处理连接丢失

c# - 如何改进我的算法以将数据存储在硬盘上?

c# - SignalR 中打开的连接列表?

.net - 视觉继承还是用户控件?

android - 获取音频时出现性能问题

c# - 如何检查修改了哪些属性/条目,哪些不在 EF 6 中编辑记录