I have two classes that perform date date range data fetching for particular days.
public class IterationLookup
{
private IList-
Further to Gabe's answer, I can confirm that the difference appears to be caused by the cost of re-constructing the delegate for every call to GetPointData.
If I add a single line to the GetPointData method in your IterationRangeLookupSingle class then it slows right down to the same crawling pace as LinqRangeLookupSingle. Try it:
// in IterationRangeLookupSingle
public TItem GetPointData(DateTime point)
{
// just a single line, this delegate is never used
Func dummy = i => i.IsWithinRange(point);
// the rest of the method remains exactly the same as before
// ...
}
(I'm not sure why the compiler and/or jitter can't just ignore the superfluous delegate that I added above. Obviously, the delegate is necessary in your LinqRangeLookupSingle class.)
One possible workaround is to compose the predicate in LinqRangeLookupSingle so that point is passed to it as an argument. This means that the delegate only needs to be constructed once, not every time the GetPointData method is called. For example, the following change will speed up the LINQ version so that it's pretty much comparable with the foreach version:
// in LinqRangeLookupSingle
public TItem GetPointData(DateTime point)
{
Func> builder = x => y => y.IsWithinRange(x);
Func predicate = builder(point);
return this.items.FirstOrDefault(predicate);
}