score:7
You can speed up that specific statement you emphasized
cas.Where(x => x.Datetime >= min && x.Datetime <= max).ToList();
With binary search over cas
list. First pre-sort cas
by Datetime
:
cas.Sort((a,b) => a.Datetime.CompareTo(b.Datetime));
Then create comparer for Record
which will compare only Datetime
properties (implementation assumes there are no null records in the list):
private class RecordDateComparer : IComparer<Record> {
public int Compare(Record x, Record y) {
return x.Datetime.CompareTo(y.Datetime);
}
}
Then you can translate your Where
clause like this:
var index = cas.BinarySearch(new Record { Datetime = min }, new RecordDateComparer());
if (index < 0)
index = ~index;
var possibleResults = new List<Record>();
// go backwards, for duplicates
for (int i = index - 1; i >= 0; i--) {
var res = cas[i];
if (res.Datetime <= max && res.Datetime >= min)
possibleResults.Add(res);
else break;
}
// go forward until item bigger than max is found
for (int i = index; i < cas.Count; i++) {
var res = cas[i];
if (res.Datetime <= max &&res.Datetime >= min)
possibleResults.Add(res);
else break;
}
Idea is to find first record with Datetime
equal or greater to your min
, with BinarySearch
. If exact match is found - it returns index of matched element. If not found - it returns negative value, which can be translated to the index of first element greater than target with ~index
operation.
When we found that element, we can just go forward the list and grab items until we find item with Datetime
greater than max (because list is sorted). We need to go a little backwards also, because if there are duplicates - binary search will not necessary return the first one, so we need to go backwards for potential duplicates.
Additional improvements might include:
Putting active codes in a
Dictionary
(keyed byValue
) outside of for loop, and thus replacing codesWhere
search withDictionary.ContainsKey
.As suggested in comments by @Digitalsa1nt - parallelize foreach loop, using
Parallel.For
, PLINQ, or any similar techniques. It's a perfect case for parallelization, because loop contains only CPU bound work. You need to make a little adjustments to make it thread-safe of course, such as using thread-safe collection forerrors
(or locking around adding to it).
score:0
There a few improvements you can make here. It might only be a minor performance increase but you should try using groupby instead of where in this circumstance.
So instead you should have something like this:
cas.GroupBy(x => x.DateTime >= min && x.DateTime <= max).Select(h => h.Key == true);
This ussually works for seaching through lists for distinct values, but in you case I'm unsure if it will provide you any benefit when using a clause.
Also a few other things you can do throughout you code:
- Avoid using ToList when possible and stick to IEnumerable. ToList performs an eager evaluation which is probably causing a lot of slowdown in your query.
- use .Any() instead of Count when checking if values exist (This only applies if the list is IEnumerable)
score:1
Try adding AsNoTracking in the list
The AsNoTracking
method can save both execution times and memory usage. Applying this option really becomes important when we retrieve a large amount of data from the database.
var possibleResults = cas.Where(x => x.Datetime >= min && x.Datetime <= max).AsNoTracking().ToList(); //around 4,6599ms
Source: stackoverflow.com
Related Query
- C# - Linq optimize code with List and Where clause
- LINQ Where clause with Contains where the list has complex object
- Linq where clause with multiple conditions and null check
- Linq with where clause in many-to-many EF Code First object
- Entity Framework with LINQ using CONTAINS in WHERE clause very slow with large integer list
- c# where in with list and linq
- Using Linq to query Entity Framework with Where clause and many-to-many relation
- Linq how to join tables with a where clause on each table and a count
- Adding AND in a WHERE clause using ViewBag and SelectList with LINQ in Controller (ASP.Net MVC)
- Entity Framework: Linq where clause compare date and time value with seconds difference
- Linq query with cartesian (wanted) and min/max in where clause
- linq to entities query which has multiple where clause and one where clause with where in condition
- CRM 2011 LINQ query with multiple inner joins and a single WHERE clause (VB .NET)
- Linq query with a join and a where clause giving an error
- Query with Linq and count matches in the Where clause and project it
- LINQ query with Distinct and WHERE clause
- Sort List by Value of SubList with where clause LINQ
- LINQ query with many tables, left outer joins, and where clause
- How to execute a linq query for each item in a list , use it in the where clause and return a collection from the result of each query?
- C# LINQ Query with group by, having and where clause invalid
- linq query with a list in the where clause
- EF LINQ to SQL is getting whole table from DB instead of selection - where clause contains list with Any statement
- Entity Framework dynamic linq where from generic source with dynamic where clause
- Linq with EF core 2.2 Condition with where Clause FK and PK
- How to combine select and group by clause with conditional where in Linq
- Linq where clause with DbFunctions.DiffDays and string comparison not working
- List is null when checking for two conditions in where clause with boolean datatype in Linq
- multiple where conditions with linq and list
- LINQ Where with AND OR condition
- lambda expression join multiple tables with select and where clause
More Query from same tag
- ParseException: No property or field '???' exists in type 'DynamicClass' when using GroupBy and Select
- how to debug `Null reference exception occured` in linq?
- getting error while trying to get "Grade" for StudentId=1
- Select Multiple Elements in XML
- Need help converting DataTable to XML VB.NET
- Find approximate duplicates in a list
- EF Core 3.1 - The LINQ expression could not be translated (left joins with group by)
- List sort based on another list
- Require Simplification On Linq To Assign Values To Dynamic Class Property
- Linq - How to delete all colum in local database window phone?
- XML get specific name
- LINQ : Left Join And Right Join with a double selection
- VB.net linq left join where null or 0
- Combing Array Inline - LINQ
- LINQ - one bool from multiple conditions of a list with objects
- Risks of using OData and IQueryable
- Creating a join Linq query to optimize looping together two lists
- convert sql to ling group by and average between 2 dates when end date can be null
- Sorting XML file by attribute value alphabetical
- Linq List Any can't handle Value command of generic List<List<T>>
- Remove elements of one list from other list
- Query by computed property in EF
- XML using LINQ with VB.NET
- How to combine list in property of object in LINQ?
- Lambda expression to step backwards in a chain based on keys
- LINQ: why does this query not work on an ArrayList?
- How do I rollback a failed InsertOnSubmit? (VB.NET LINQ)
- Linq get all objects that implement interface
- Find string in text with linq regardless of case or culture
- Attaching Issue in Entity Framework