开发者

Does the compiler concatenate LINQ where queries?

开发者 https://www.devze.com 2023-04-03 23:01 出处:网络
Consider the two following similar code samples. One where clause. bool validFactory = fields .Where( fields => field.FieldType == typeof( DependencyPropertyFactory<T> ) &&

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开发者_StackOverflow 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?


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消