Reputation: 10422
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
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
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