score:8
This should remove the 10k as a multiple by, and just do it once?
What it means is that instead of iterating personList
100k times, performing the where
and select
operations for each of those iterations that you'll be iterating the resulting List
100k times, and that the where
and select
operations will only have been performed on the underlying data source once.
The question is that this seems too easy, and I'm sure the LINQ is doing something clever somewhere that should mean that this doesn't happen.
Nope, your first query is simply something that you shouldn't be doing using LINQ, you should be taking the results of the query and placing them into a data structure if you plan to iterate over them many times (which is what you changed).
You can improve this query even more by using the appropriate data structure. Searching on a List
is rather inefficient, as it needs to do a linear search. It would be preferable to use a HashSet
to store the results of the query. A HashSet
has O(1) search speed in the average case, as opposed to O(n) search time of a List
.
var dates = new HashSet<DateTime>(from Person p in personList
where p.OrganisationID = 123
select p.Birthday);
foreach (DateTime d in dateList.Where(date => dates.Contains(date)))
{
Console.WriteLine(string.Format("Date: {0} has a Birthday", d.ToShortDateString()));
}
score:0
I'm assuming that you are referring to LINQ-to-Objects, as each LINQ provider has its own implementation (LINQ-to-SQL, LINQ-to-Entities, LINQ-to-XML, LINQ-to-anything).
Taking your example of personBirthdays
, it is not a foregone conclusion that the expression was created for the purpose of iterating through the full result set, so LINQ cannot automatically materialize the results to an array or list.
These operations are very different:
personBirthdays.Distinct()
personBirthdays.FirstOrDefault(b => b.Month == 7)
personBirthdays.Select(b => b.Year).Distinct()
What LINQ as a technology does that is "clever" is to allow the construction of an expression tree and to defer execution. This is what prevents--in the 3rd example above--100k iteration to get birthdays, then another 100k to choose the year, then a final, costly pass to assemble the distinct values.
The LINQ consumer (you) has to own the destiny of the expression. If you know that the result set will be iterated over multiple times, the onus is on you to materialize them to an array or list.
score:3
This is typical select n+1
problem, and after you applied .ToList()
you have partially solved it. Next step could be following: you're constantly iterating over personBirthdays
list, replace it with HashSet
and you could perform Contains(d)
much much faster and remove duplicates:
var personBirthdays = new HashSet<DateTime>((from Person p in personList
where p.OrganisationID = 123
select p.Birthday).ToArray());
Source: stackoverflow.com
Related Query
- Does this LINQ code perform multiple lookups on the original data?
- How does linq actually execute the code to retrieve data from the data source?
- LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression
- Why does the C# compiler go mad on this nested LINQ query?
- The data source does not support server-side data paging
- LINQ to Entities does not recognize the method 'System.DateTime AddSeconds(Double)' method, and this method cannot be translated into
- LINQ to Entities does not recognize the method 'Int32 Int32(System.String)' method, and this method cannot be translated into a store expression
- LINQ to Entities does not recognize the method 'Int32 ToInt32(System.Object)' method, and this method cannot be translated into a store expression
- LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression
- Enumerable.Empty<T>().AsQueryable(); This method supports the LINQ to Entities infrastructure and is not intended to be used directly from your code
- Is there any way to create a LINQ query as a variable without having the data source (yet)?
- What is the purpose of using "Select" multiple times in this LINQ query?
- Does this linq query run on every iteration of the for-each loop?
- How does this linq code that splits a sequence work?
- multiple orderby in this linq code
- LINQ to Entities does not recognize the method 'Int32 ToInt32(System.String)' method, and this method cannot be translated into a store expression
- What is the return type for a anonymous linq query select? What is the best way to send this data back?
- Refactor Linq code and "LINQ to Entities does not recognize the method"
- Why does the StringComparison.InvariantCultureIgnoreCase not work with this Db4o linq query?
- LINQ to Entities does not recognize the method 'System.String ToString(Int32)' method, and this method cannot be translated into a store expression
- Does Entity Framework query the database multiple times if I use different fields of the same Linq query at different times?
- When selected into an object; does Linq To SQL still perform the logic in a SQL Query?
- When does this LINQ query go to the database?
- LINQ to Entities does not recognize the method 'Double ToDouble(System.String)' method, and this method cannot be translated into a store expression
- Where does this Linq statement get the selected value from?
- LINQ to Entities does not recognize the method and this method cannot be translated into a store expression
- Why does this LINQ query assign a value of 1 to a NULL value from the database?
- why does this linq code get exponentially slower when applying First() to projection?
- LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression
- How to swap the data source associated with a Linq query?
More Query from same tag
- Tracking last visited nodes - C#
- How to select only one column to return an object in linq
- Filtering a list of processes based on a list of string objects
- Dynamic where clause with two entity
- Convert string to LINQ query
- LINQ - Operator to be used to return all records
- How to successfully join two in-memory linq collections?
- Linq query that does left join and group by having count()
- How to return sum value from using group by, having and sum by using LINQ in C#
- DataGridView AddRange, Cast IEnumerable<object[]> to DataGridViewRow[] (If possible, using LINQ)
- Efficient way to get a huge number of records sorted via Linq. Also some help regarding editing an existing DB entry
- Linq equivalent statement for SQL Inner Join with IN statement
- How would this query translate into a dynamic Linq expression?
- Why is DataItem always null in the Page_Load handler?
- How to convert a var which contains Long to an Long[]
- Converting LINQ Extension method to work with L2E
- Inserting multiple custom items into listview
- How to apply contain on last record and delete if found in LINQ?
- Checking if a list is included in a property which is a string?
- Linq query null check in data source
- Access child token in JSON
- Delete query with Where in LINQ
- C# Joining List<of type> and handling NULL/Empty values
- Why are some object properties UnaryExpression and others MemberExpression?
- EntityFramework - LINQ Join help
- "..cannot be inferred from the usage." How can I insert both a where and an orderby expression into this sqlite query?
- Linq syntax to find subtotal of grouped rows in a DataTable and update the DataTable
- LINQ to XML - accessing descendants with a prefix
- Find 2nd max salary using linq
- Linq query to d3.js chart