Following is the use-case:
- Sorted List of
DateTimetype, with granularity in the millisecond - Search for nearest
DateTime, which satisfy the suppliedpredicatedelegate - Performance is an issue, since List has 100K+ records, total time span of 10 hours from minimum to maximum index and lot of frequent calls (50+ / run), impacts performance
What we currently do, custom binary search as follows ?
public static int BinaryLastOrDefault<T>(this IList<T> list, Predicate<T> predicate)
{
var lower = 0;
var upper = list.Count - 1;
while (lower < upper)
{
var mid = lower + ((upper - lower + 1) / 2);
if (predicate(list[mid]))
{
lower = mid;
}
else
{
upper = mid - 1;
}
}
if (lower >= list.Count) return -1;
return !predicate(list[lower]) ? -1 : lower;
}
Can I use Dictionary to make it O(1) ?
- My understanding is No, since the input value may not be there and in that case we need to return the closest value, which if in above code returns -1, then last element in the sorted list is the expected result
Following is the option I am considering
- Data structure like
Dictionary<int,SortedDictionary<DateTime,int>> - Total duration DateTime duration between highest and lowest value is 10 hours ~ 10 * 3600 * 1000 ms = 36 million ms
- Created buckets of 60 sec each, total number of elements ~
36 million / 60 K = 600 - For any supplied DateTime value, its now easy to find the Bucket, where limited number of values can be stored as
SortedDictionary, with key as DateTime value and original index as value, thus if required then data can enumerated to find the closest index
In my understanding this implementation, will make the search much faster than Binary search detailed above, since data searched would be substantially reduced, Any suggestion what more can be done to improve the search time further to further improve it in the algorithmic terms, I can try the Parallel options for various independent calls separately