编译器是否连接LINQ where查询?
本文关键字:查询 where LINQ 是否 连接 编译器 | 更新日期: 2023-09-27 18:08:11
考虑下面两个类似的代码示例。
1个where
条款
bool validFactory
= fields
.Where(
fields => field.FieldType == typeof( DependencyPropertyFactory<T> ) &&
field.IsStatic )
.Any();
两个where
条款
bool validFactory
= fields
.Where( field => field.FieldType == typeof( DependencyPropertyFactory<T> ) )
.Where( field => field.IsStatic )
.Any();
我更喜欢后者,因为我发现它更具可读性,而且它引起的格式化问题更少,特别是在使用自动格式化时。当在单独的条件旁边(甚至上面)放置注释以澄清意图时,也会更清楚。
我的直觉告诉我第二个代码示例的效率会更低。当然,我可以自己编写一个简单的测试(如果没有人知道答案,我也会这么做)。现在我认为这是完美的食物。; p
- 一个比另一个更有效率吗?
- 编译器是否足够智能来优化这个?
编译器不尝试优化连续的"where"调用。运行库有。如果你有一大堆"where"answers"select"调用,运行时将尝试将它们重新组织成更有效的形式。
在一些不寻常的情况下,"优化"当然会使事情变得更糟。我似乎记得Jon Skeet最近写了一篇关于这个的文章,尽管我不确定它在哪里。
编译器不允许优化这个,因为它不知道Where()做什么。例如,您可能重载了Where(),并使用记录其结果的版本。(抖动可以做优化,但在实践中不太可能)
效率差异不太可能显著。你可以分析你的应用程序,看看它是否重要。
Update:显然抖动在这里执行优化。请看Eric Lippert的回答
我不认为这里有什么显著的区别。然而,如果你强制枚举集合,那么我希望有更大的差异
bool validFactory = fields
.Where( field => field.FieldType == typeof( DependencyPropertyFactory<T> ) )
.ToList()
.Where( field => field.IsStatic )
.ToList()
.Any();
在您的两个原始代码示例中,我看到相同的执行-第一个项目检查FieldType
,然后检查IsStatic
,如果它存在,则返回true。否则选中第二项,依此类推。不需要解析整个集合
在上面的示例中,将独立于IsStatic
检查为FieldType
解析整个集合。这可能会降低效率。注意,这在您的代码片段中都是不必要的。