LINQ是否知道如何优化“查询”?

5
假设我做了类似以下的事情:
 var Ordered = MyList.OrderBy(x => x.prop1).ThenBy(x => x.prop2); 

MyList.OrderBy(x => x.prop1).ThenBy(x => x.prop2)返回一个排序后的列表,并按照prop1排序,然后按照prop2进一步筛选该列表。换句话说,它等同于:

var OrderedByProp1 = MyList.OrderBy(x => x.prop1);
var Ordered = OrderedByProp1.OrderBy(x => x.prop2);

显然,可以通过运行带有比较器的排序算法来优化此过程:

var Ordered = MyList.Sort( (x,y) => x.prop1 != y.prop1 ? x.prop1 < y.prop1 : ( x.prop2 < y.prop2 ) );

如果它确实进行某种优化,并且在该过程中未返回中间列表,那么它是如何知道如何执行该操作的?如何编写一个类使其自己优化方法链?这没有意义。

LINQ 的哪个版本?LINQ to Objects,LINQ to Entities 等等? - Daniel Mann
如果使用Linq to Entities,那么是哪个Linq提供程序?有很多选择。请注意,EF7中的更改使得Linq to Entities提供程序更容易优化查询。 - Eric J.
如果您正在连接到数据库,请使用SQL Profiler比较每种情况下生成的数据库查询,并查看它们之间的差异(如果有)。 - ChrisF
LINQ(针对对象)不会“优化”查询,但它尽可能地做最少的工作,并且通常会产生“足够好”的结果。它不是万能的解决方案,对于高性能代码,您可能需要手动编写所有内容(例如,Roslyn不允许在内部使用LINQ,因为直接循环更容易预测真实成本)。相反,它也可以完全适用于高性能代码,我在当前系统中跨数百万条记录连续使用L2O。性能始终是分析、分析和分析。 - Chris Marisic
1个回答

7

MyList.OrderBy(x => x.prop1) 返回的不是过滤后的列表。

LINQ 方法(至少通常情况下)返回的是查询,而不是执行这些查询的结果。

OrderBy 只是返回一个对象,当您请求其中一项时,它将按照特定顺序返回集合中的第一项。但在您实际请求结果之前,它什么也没做。

请注意,您还可以通过查看 OrderBy 返回的内容来大致了解正在发生的情况。它返回 IOrderedEnumerable<T>。该接口有一个方法 CreateOrderedEnumerable,它:

根据键对 IOrderedEnumerable 的元素执行后续排序。

这个方法是 ThenBy 用来指示是否有后续排序的方法。

这意味着,在您需要生成结果集中的单个项目之前,您正在从 OrderBy 和所有 ThenBy 调用中构建要使用的所有比较器。

有关如何精确创建此行为的更多详细信息,请参见Jon Skeet 在此主题上的博客系列


即使Jon Skeet不回答一个问题,他也回答了一个问题。 - Juan Lopes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接