2

Is there any difference between using LinQ to filter compared to using a collections Where() method.

More specifically,

First

var numQuery = from num in numbers
               where (num % 2) == 0
               select num;

Second

var numQuery = numbers.Where(num => num % 2 == 0);

In the above query, which is better? And is there any performance consideration?

Thanks.

linquize
  • 19,828
  • 10
  • 59
  • 83
Koda
  • 1,709
  • 3
  • 14
  • 15
  • Not sure if your code gets optimised down but I would think that using "(num & 1) == 0" would be quicker. – MikeKulls Sep 06 '12 at 03:30

3 Answers3

6

There is no difference. The first one is the Query Type LINQ. The second one is the Extension Method type. I'll prefer the second one because it has many built-in functionalities.

from the link below

"...however there is no semantic difference between method syntax and query syntax."

MSDN: LINQ Query Syntax versus Method Syntax (C#)

John Woo
  • 258,903
  • 69
  • 498
  • 492
5

No, there is no difference at all (just as John pointed out).

To convince anyone who is not willing to believe, I've checked what IL code is produced, and it is exactly the same (posted below for those being curious):


IL_0001:  ldc.i4.4    
IL_0002:  newarr      System.Int32
IL_0007:  dup         
IL_0008:  ldtoken     {A078DB01-D7BE-45F4-8D98-8D2FA673C282}.$$method0x6000001-1
IL_000D:  call        System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray
IL_0012:  stloc.0     
IL_0013:  ldloc.0     
IL_0014:  ldsfld      UserQuery.CS$9__CachedAnonymousMethodDelegate1
IL_0019:  brtrue.s    IL_002E
IL_001B:  ldnull      
IL_001C:  ldftn       b__0
IL_0022:  newobj      System.Func..ctor
IL_0027:  stsfld      UserQuery.CS$9__CachedAnonymousMethodDelegate1
IL_002C:  br.s        IL_002E
IL_002E:  ldsfld      UserQuery.CS$9__CachedAnonymousMethodDelegate1
IL_0033:  call        System.Linq.Enumerable.Where
IL_0038:  stloc.1     
IL_0039:  ldloc.1     
IL_003A:  call        LINQPad.Extensions.Dump

b__0:
IL_0000:  ldarg.0     
IL_0001:  ldc.i4.2    
IL_0002:  rem         
IL_0003:  ldc.i4.0    
IL_0004:  ceq         
IL_0006:  stloc.0     
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.0     
IL_000A:  ret     
John Woo
  • 258,903
  • 69
  • 498
  • 492
Maciek Talaska
  • 1,628
  • 1
  • 14
  • 22
  • @JohnWoo thanks :) I thought it may be one of the ways to convince people for 100% that it is the same :) – Maciek Talaska Sep 06 '12 at 02:30
  • 1
    @JohnWoo I'm still fairly new here and trying to get how things work. Did you edit this post and add only a single space? – MikeKulls Sep 06 '12 at 03:32
  • @MaciekTalaska: Its exactly the same because compiler converts query type to method type at compile time. Acc to this http://msdn.microsoft.com/en-us/library/bb397947.aspx – Nikhil Agrawal Sep 06 '12 at 04:07
  • @NikhilAgrawal and that is the whole point of making it obvious to everyone - is there any better proof than providing a IL code? – Maciek Talaska Sep 06 '12 at 04:08
  • @MaciekTalaska: Can you help me in by telling from where do you produce this IL Code? I also want to do so. – Nikhil Agrawal Sep 06 '12 at 04:11
  • @NikhilAgrawal for such small code snippets I am using LinqPad (http://www.linqpad.net/) but you may also use one of the freely available .net decompilers: Telerik JustDecompile, JetBrains DotPeek, ILSpy (open source). – Maciek Talaska Sep 06 '12 at 04:20
0

using Where() extension method does not need the select part Select(a => a) if you return the instance of each entry.

Query type expression always need the select part select a at the end of the expression, which looks redundant but required by the syntax.

Moreover, First() extension method does not have a corresponding query type syntax. So you need to add brackets to query type expression (from a in b where a > 0 select a).First() For nested query, you also need to add brackets to query type expression. I can use b.First(a > 0) directly instead of b.Where(a > 0).First()

Therefore, I advocate using extension methods.

linquize
  • 19,828
  • 10
  • 59
  • 83