Atish Kumar Dipongkor
Atish Kumar Dipongkor

Reputation: 10422

What is the difference between following two statements?

We can count process by the following statement

var query = Process.GetProcesses()
             .Where(m => m.ProcessName.StartsWith("S")).Count();

But ReShaper suggests me like following statement

var query = Process.GetProcesses().Count(m => m.ProcessName.StartsWith("S"));

My question is ... Which one is better if I consider performance issue???

Upvotes: 3

Views: 225

Answers (2)

Abbas Amiri
Abbas Amiri

Reputation: 3204

The IL result of two queries are:

Process.GetProcesses().Count(m => m.ProcessName.StartsWith("S"));

IL_0001:  call        System.Diagnostics.Process.GetProcesses
IL_0006:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_000B:  brtrue.s    IL_0020
IL_000D:  ldnull      
IL_000E:  ldftn       b__0
IL_0014:  newobj      System.Func<System.Diagnostics.Process,System.Boolean>..ctor
IL_0019:  stsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_001E:  br.s        IL_0020
IL_0020:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_0025:  call        System.Linq.Enumerable.Count

Process.GetProcesses().Where(m => m.ProcessName.StartsWith("S")).Count();

IL_0001:  call        System.Diagnostics.Process.GetProcesses
IL_0006:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_000B:  brtrue.s    IL_0020
IL_000D:  ldnull      
IL_000E:  ldftn       b__0
IL_0014:  newobj      System.Func<System.Diagnostics.Process,System.Boolean>..ctor
IL_0019:  stsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_001E:  br.s        IL_0020
IL_0020:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate1
IL_0025:  call        System.Linq.Enumerable.Where
IL_002A:  call        System.Linq.Enumerable.Count

b__0:
IL_0000:  ldarg.0     
IL_0001:  callvirt    System.Diagnostics.Process.get_ProcessName
IL_0006:  ldstr       "S"
IL_000B:  callvirt    System.String.StartsWith
IL_0010:  stloc.0     // CS$1$0000
IL_0011:  br.s        IL_0013
IL_0013:  ldloc.0     // CS$1$0000
IL_0014:  ret 

The reason is obvious, isn't it?

The difference of execution time is not very considerable, but the first one has less method call, so it seems better.

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236268

First statement will create WhereIterator internally, which will iterate over source and apply predicate. Count calculation will look like:

var iterator = new WhereArrayIterator<TSource>((TSource[]) source, predicate);

int num = 0;

using (IEnumerator<TSource> enumerator = iterator.GetEnumerator())
{
   while (enumerator.MoveNext())
       num++;      
}

return num;

But second statement will not create iterator - it will apply predicate while iterating directly over source sequence:

int num = 0;

foreach (TSource local in source)
{
    if (predicate(local))        
        num++;        
}

return num;

So, second statement has slightly better performance.

Upvotes: 4

Related Questions