EDIT
According to the statement that dasblinkenlight's answer , as a rule, I wrote a short helper helper function.
public static int BinaryFirstIndexOf<T>( Func<int, T> indexer, Func<T, boo> predicate, int count) { var low = 0; var high = count - 1; while (low < (high - 1)) { var mid = low + ((high - low) / 2); if (predicate(indexer(mid)) { high = mid; } else { low = mid; } } if (predicate(indexer(low))) { return low; } if (low != high && predicate(indexer(high))) { return high; } return -1; }
What will I use so
var time = DateTime.Now.AddDays(-1); var c = scan.Entries; var first = BinaryFirstIndexOf( i => c[i], e => e.TimeGenerated > time, c.Count); if (first >= 0) { var result = new List<Item>(c.Count - first); Enumerable.Range(first, c.Count - first).AsParallel() .ForAll(i => { var j = i - first; result[j] = (Item)c[i]; }); }
Do not want to do something like this
var time = DateTime.Now.AddDays(-1); var c = scan.Entries; var cutOff = 0; for (var i = c.Count - 1; i > - 1; i--) { if (c[i].TimeGenerated < time) { cutOff = i; break; } } var result = new List<Item>(c.Count - cutOff - 1); var j = 0; for (var i = cutOff + 1; i < c.Count; i ++) { result[j] = (Item)c[i]; j++; }
I assume that the data you want is at the end and occupies less than half of this collection.
Or perhaps using linq for parallel processing,
var time = DateTime.Now.AddDays(-1); var c = scan.Entries; var cutOff = 0; for (var i = c.Count - 1; i > - 1; i--) { if (c[i].TimeGenerated < time) { cutOff = i; break; } } var result = new List<Item>(c.Count - cutOff - 1); Enumerable.Range(cutOff + 1, c.Count - cutOff - 1).AsParallel() .ForAll(i => { var j = i - cutOff - 1; result[j] = (Item)c[i]; });
source share