编译器是否连接 LINQ where 查询?

发布于 2024-12-04 02:27:59 字数 723 浏览 2 评论 0原文

考虑以下两个类似的代码示例。

一个 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();

我更喜欢第二种,因为我发现它更具可读性,并且会导致更少的格式问题,尤其是在使用自动格式时。当在单独的条件旁边(甚至上面)放置注释以阐明意图时,它也会更清晰。

我的直觉表明第二个代码示例的效率会较低。我当然可以自己编写一个简单的测试(如果没有人知道答案,我也会这样做)。现在我认为这对SO来说是完美的食物。 ;p

  1. 一个比另一个更有效率吗?
  2. 编译器是否足够聪明来优化它?

Consider the two following similar code samples.

One where clause.

bool validFactory
  = fields
    .Where(
      fields => field.FieldType == typeof( DependencyPropertyFactory<T> ) &&
                field.IsStatic )
    .Any();

Two where clauses.

bool validFactory
  = fields
    .Where( field => field.FieldType == typeof( DependencyPropertyFactory<T> ) )
    .Where( field => field.IsStatic )
    .Any();

I prefer the second since I find it more readable and it causes less formatting issues, especially when using auto-formatting. It is also clearer when placing comments next to the separate conditions (or even above) to clarify the intent.

My intuition says the second code sample would be less efficient. I could of course write a simple test myself (and will if nobody knows the answer). For now I thought this is perfect food for SO. ;p

  1. Is one more efficient than the other?
  2. Is the compiler smart enough to optimize this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

东风软 2024-12-11 02:27:59

编译器不会尝试优化连续的“where”调用。 运行时库会这样做。如果您有一大堆彼此相邻的“where”和“select”调用,运行时将尝试将它们重新组织成更有效的形式。

在一些不寻常的情况下,“优化”当然会让事情变得更糟。我似乎记得乔恩·斯基特最近写了一篇关于此事的文章,尽管我不确定它在哪里。

The compiler does not attempt to optimize successive "where" calls. The runtime library does. If you have a whole bunch of "where" and "select" calls beside each other, the runtime will attempt to reorganize them into a more efficient form.

In some unusual cases, of course the "optimization" turns out to make things worse. I seem to recall that Jon Skeet wrote an article about that recently, though I'm not sure where it is.

呆萌少年 2024-12-11 02:27:59

编译器不允许对此进行优化,因为它不知道Where() 的作用。例如,您可能使用记录其结果的版本重载了Where()。 (抖动可以进行优化,但实际上不太可能。)

效率差异不太可能很大。您可以分析您的应用程序,看看它是否重要。

更新:显然抖动确实在这里执行优化。请参阅埃里克·利珀特的回答。

The compiler is not allowed to optimize this because it doesn't know what Where() does. For example you may have overloaded Where() with a version which logs its results. (The jitter could do optimization, but in practice it is unlikely to.)

The efficiency difference is unlikely to be significant. You can profile your application to see if it matters.

Update: Apparently the jitter does perform optimization here. See Eric Lippert's answer.

笑着哭最痛 2024-12-11 02:27:59

我不认为这里会有显着差异。但是,如果您强制枚举集合,那么我会期望有更多差异

bool validFactory   = fields
    .Where( field => field.FieldType == typeof( DependencyPropertyFactory<T> ) )
    .ToList()
    .Where( field => field.IsStatic )     
    .ToList()
    .Any(); 

在您的两个原始代码示例中,我看到相同的执行 - 第一项检查 FieldType,然后检查 IsStatic,如果存在则返回true。否则检查第二项,依此类推。不需要解析整个集合。

在上面的示例中,将独立于 IsStatic 检查来解析整个集合的 FieldType。这可能会降低效率。请注意,这在您的两个片段中都不是必需的。

I wouldn't expect a significant difference here. However if you forced enumeration of the collection then I would expect more difference

bool validFactory   = fields
    .Where( field => field.FieldType == typeof( DependencyPropertyFactory<T> ) )
    .ToList()
    .Where( field => field.IsStatic )     
    .ToList()
    .Any(); 

In your two original code samples I see identical execution - the first item is checked for FieldType, then checked for IsStatic, and if it exists then return true. Else the second item is checked, and so on. The entire set does not need to be parsed.

In the sample above the entire set will be parsed for FieldType independently of the IsStatic check. This it's likely to be less efficient. Note that this isn't necessary in either of your snippets.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文