Fastest way to check list <T> for date
I have a list of dates on which the machine worked, but it does not include the date when the machine was turned off. I need to create a list of worked days and not work. I am not sure of the best way to do this. I started by increasing all range days and checking to see if there is a date in the list, iterating through the whole list every time. I am looking for more effective ways to find dates.
class machineday { datetime WorkingDay; } class machinedaycollection : List<machineday> { public List<TimeCatEvent> GetAllByCat(string cat) { _CategoryCode = cat; List<machineday> li = this.FindAll(delegate(machinedaydummy) { return true; }); li.Sort(sortDate); return li; } int sortDate(machinedayevent1, machinedayevent2) { int returnValue = -1; if (event2.date < event1.date) { returnValue = 0; } else if (event2.date == event1.date) { //descending returnValue = event1.date.CompareTo(event2.date); } return returnValue; } } Sort dates and iterate the resulting list in parallel with increasing the counter. Whenever the counter does not match the current item in the list, you find a date that is not in the list.
List<DateTime> days = ...; days.Sort(); DateTime dt = days[0].Date; for (int i = 0; i < days.Length; dt = dt.AddDays(1)) { if (dt == days[i].Date) { Console.WriteLine("Worked: {0}", dt); i++; } else { Console.WriteLine("Not Worked: {0}", dt); } } (It is assumed that there are no duplicate days in the list.)
Create a list of valid dates and subtract the daily collection from it using the LINQ Enumerable.Except extension method. Something like that:
IEnumerable<DateTime> dates = get_candidate_dates(); var holidays = dates.Except(machinedays.Select(m => m.WorkingDay)); The get_candidate_dates() method can even be an iterator that generates all dates within the range on the fly, rather than a pre-saved list of all dates.
The methods listed are reasonably smart and usually do a decent job on the performance side, but if you need the fastest algorithm, it will depend on how you plan to use the result.
Sorry guys, but I don't really like your decisions. I think you should create a HashTable with your dates. You can do this by interacting only once on business days.
Then you process the entire range of days and for each request that you request in the hash table, if the date exists or not, using
myHashTable.ContainsKey(day); // this is efficient Simple, elegant and fast.
I think your solution uses exponential time, it is single-line or logarithmic (which is actually good).
Assuming the list is sorted and the machine runs βmost of the timeβ, you can avoid iterating over all dates by grouping dates by month and skipping dates between them. Something like this (you need to clear):
int chunksize = 60; // adjust depending on data machineday currentDay = myMachinedaycollection[0]; for (int i = 0; i < myMachinedaycollection.Count; i += chunksize) { if (currentDay.WorkingDay.AddDays(chunksize) != myMachinedaycollection[i + chunksize].WorkingDay) { // write code to iterate through current chunk and get all the non-working days } currentDay = myMachinedaycollection[i + chunksize]; } I doubt that you want the list of days to work and not work.
The title of the question suggests that you want to know if the system was on a specific date. It also seems reasonable to calculate% uptime. None of them require the creation of a list of all time points in the interval.
Sort the service time. For the first question, do BinarySearch for the date you are interested in and check if the previous record was offline in the system with maintenance or return to service. During% uptime, take off (down for maintenance, restore service) differently, use subtraction to find the duration of maintenance, add them. Then use subtraction to find the length of the full interval.
If your question does not really mean that you tracked maintenance intervals (or equivalent usage intervals), you can ignore this answer.