Linq – 找出延期执行的最快方法是什么?

找出哪些.net框架linq方法(例如.IEnumerable linq方法)使用延迟执行而不是使用延迟执行实现的最快方法是什么。

在编码很多次的时候,我想知道这个是否会以正确的方式执行。 找出答案的唯一方法是访问MSDN文档以确保。 会不会有更快的方式,任何目录,网络上的任何列表,任何备忘单,你可以分享的任何其他技巧? 如果是,请这样做。 这将有助于许多linq新手(像我一样)减少错误。 唯一的另一个选择是检查文档,直到一个人使用它们足以记住(这对我来说很难,我往往不记得某些地方记录的“任何东西”,可以查找:D)。

通常,返回序列的方法使用延迟执行:

IEnumerable ---> Select ---> IEnumerable 

和返回单个对象的方法不会:

 IEnumerable ---> First ---> Y 

因此,像WhereSelectTakeSkipGroupByOrderBy使用延迟执行,因为它们可以,而FirstSingleToListToArray则不会,因为它们不能。

还有两种类型的延迟执行。 例如, Select方法在被要求生成项目时一次只能获得一个项目,而OrderBy方法在被要求返回第一个项目时必须使用整个源项目。 因此,如果您在Select之后链接OrderBy ,则执行将推迟到您获得第一个项目,但随后OrderBy将询问所有项目的Select

我使用的指南:

  • 始终假设任何返回IEnumerableIQueryable API都可以使用延迟执行。 如果您正在使用这样的API,并且需要多次迭代结果(例如,获取Count),则在执行此操作之前转换为集合(通常通过调用.ToList()扩展方法。

  • 如果您正在公开枚举,请始终将其公开为集合( ICollectionIList ),如果这是您的客户通常会使用的。 例如,数据访问层通常会返回域对象的集合。 如果延迟执行是您正在公开的API的合理选项,则仅公开IEnumerable

实际上,还有更多; 此外,您需要考虑缓冲与非缓冲。 OrderBy可以延迟,但迭代时必须使用整个流。

通常,返回IEnumerable的LINQ中的任何内容都会延迟 – 而Min等(返回值)不会延迟。 缓冲(与非)通常可以被推理,但坦率地说reflection器是一种非常快速的方法来确定。 但请注意,无论如何,这通常是一个实现细节。

请参阅MSDN上按执行方式分类标准查询运算符:

https://msdn.microsoft.com/en-us/library/bb882641(v=vs.110).aspx

对于实际的“延迟执行”,您需要适用于IQueryable的方法。 基于IQueryable的方法链,用于构建表示查询的表达式树。 只有当你调用一个接受IQueryable并产生具体或IEnumerable结果的方法(ToList()和类似的,AsEnumerable()等)时,Linq提供者才会评估它(Linq2Objects内置于Framework中,Linq2SQL和现在MSEF;其他ORM和持久层框架也提供Linq提供者)并返回实际结果。 可以使用AsQueryable()扩展方法将框架中的任何IEnumerable类强制转换为IQueryable,并且将转换表达式树的Linq提供程序(如ORM)将提供AsQueryable()作为linq查询的跳转点。他们的数据。

即使对于IEnumerable,一些Linq方法也是“懒惰的”。 因为IEnumerable的优点在于您不必了解所有内容,只有当前元素以及是否存在另一个元素,作用于IEnumerable的Linq方法通常会返回一个迭代器类,每当从其源中吐出一个对象时后来在链中的方法要求一个。 任何不需要了解整个集合的操作都可以进行延迟评估(选择和哪里有两个大的;还有其他的)。 确实需要了解整个集合(通过OrderBy进行排序,使用GroupBy进行分类以及像Min和Max这样的聚合)将会将其整个源可以插入到List或Array中并对其进行处理,从而强制通过所有更高节点评估所有元素。 一般来说,如果你能帮助它们,你希望这些在方法链中迟到。

如果使用.AsQueryable()将集合强制转换为IQueryable,则LINQ调用将使用延迟执行。

请参阅此处: 使用IQueryable与Linq