score:2
I've created a simple test console app.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace LinqPerformance
{
class Program
{
static void Main(string[] args)
{
var data = Enumerable.Range(1, 100000000);
for (int x = 0; x < 10; x++)
{
ExecuteMethods(data);
}
}
private static void ExecuteMethods(IEnumerable<int> data)
{
Method1("linq collection", () =>
{
var collection = data.Where(d => d % 2 == 0);
double count = 0;
foreach (var c in collection)
{
count += c;
}
});
Method1("list collection", () =>
{
var collection = data.Where(d => d % 2 == 0).ToList();
double count = 0;
foreach (var c in collection)
{
count += c;
}
});
Method1("iterable collection", () =>
{
double count = 0;
foreach (var c in data.Where(d => d % 2 == 0))
{
count += c;
}
});
}
private static void Method1(string name, Action body)
{
Stopwatch s = new Stopwatch();
s.Start();
body();
s.Stop();
Console.WriteLine(name + ": " + s.Elapsed);
}
}
}
After running this I can see that the ToList() is the slowest. The other two approaches appear to be the same.
I suppose this is because the foreach is expanded to a
var enumerator = collection.GetEnumerator();
while(enumerator.MoveNext() )
{
var c = enumerator.Current;
count += c;
}
score:1
Performance is the same, whether you assign the Linq query to a variable, or call it directly in the For Each. In both case the iterator will be created once and the For Each loop will go through each item in the list once.
In the first code sample, the CType is not necessary though (actually I don't think it would work). You can simply do:
Dim collection = CellCollection.Where(Function(i) i.IsPending = True)
For Each item As Item In collection
'Do something here
Next
But as I mentioned, assigning to a variable is not necessary. Having the Where clause on the For Each line will yield the same performance, and the code will be shorter and more readable.
score:0
The performance for both is the same. foreach
will create the IEnumerable(Of T)
then enumerate through it.
However, if you're concerned about performance, try:
Dim collection As IEnumerable(Of Item) _
= CellCollection.Where(Function(i) i.IsPending)
For Each item As Item In collection
'Do something here
Next
It's possible that casting the IEnumerable(Of Item)
to ItemCollection
would cause it to enumerate (like ToArray
or ToList
). This will cause the collection to enumerate twice. Keeping it as IEnumerable
ensures that the i.IsPending
check happens during the enumeration of the For Each
and not the CType()
.
The fastest solution would be to forgo LINQ altogether (LINQ statements, although readable, add some overhead).
For Each item As Item In CellCollection
If Not item.IsPending Then
Continue For
End If
'Do something here
Next
Source: stackoverflow.com
Related Articles
- LINQ Source Code Available
- creating Linq to sqlite dbml from DbLinq source code
- Performance and Linq in iterations
- source code for LINQ 101 samples
- c# Linq or code to extract groups from a single list of source data
- Convert string[] to int[] in one line of code using LINQ
- Code equivalent to the 'let' keyword in chained LINQ extension method calls
- Linq code to select one item
- LINQ performance FAQ
- How are people unit testing code that uses Linq to SQL
- Performance of LINQ Any vs FirstOrDefault != null
- foreach + break vs linq FirstOrDefault performance difference
- For vs. Linq - Performance vs. Future
- What is the Efficiency and Performance of LINQ and Lambda Expression in .Net?
- LINQ performance Count vs Where and Count
- Aggregate vs Sum Performance in LINQ
- Is multiple .Where() statements in LINQ a performance issue?
- Linq ToList/ToArray/ToDictionary performance
- SQL vs LINQ performance
- LINQ Performance for Large Collections
- LINQ Lambda vs Query Syntax Performance
- LINQ query to perform a projection, skipping or wrapping exceptions where source throws on IEnumerable.GetNext()
- Performance concern when using LINQ "everywhere"?
- Performance for using 2 where clauses in LINQ
- Why I lose performance if I use LINQ on MongoDB?
- Performance Difference between LINQ and Stored Procedures
- I am wondering about the state of connection and impact on code performance by 'yield' while iterating over data reader object
- Syntax to execute code block inside Linq query?
- OrderBy and Top in LINQ with good performance
- Slow foreach() on a LINQ query - ToList() boosts performance immensely - why is this?
- Any way to access to a variable of type "var", defined in code behind, from aspx file?
- How do I get previous key from SortedDictionary?
- Convert DataTable to Dictionary<string,string> specifying the column-names involved, not using foreach
- How to retrieve a CRM entity record by matching to an EntityReference
- Sequence contains no elements even though I add OrDefault
- Flatten/Merge List using Linq
- How to find first occurrence with LINQ
- C# Core 2.0 - get data from one model based on data in another model?
- Select inside a select query (lists)
- How to select with multiple condition in linq?
- How do I create hierarchical query with where condition on the children collection
- LINQ: combining join and group by
- Convert flat collection to one-?many C#/Linq
- How to show at listbox2 value by select value from listbox1 (by id) c#
- NHibernate select query
- dictonary requeiers a model item of type system.collections.generic.ienumeruble
- Refactoring LINQ to Entities queries with let variables and sub-queries
- Problem in LINQ Query
- Where is the implicit cast from TDelegate to Expression<TDelegate> declared?
- How to create subcolumns in RadGridView?