Alex
Alex

Reputation: 59

Linq performance poor

In a for loop I run the following code:

IEnumerable<KeyValuePair<DateTime, double>> avrPrefMinute = d_averagesPerMinute.Where(n => n.Key == minuteAverage.Key.Subtract(new TimeSpan(0, i, 0)));

This loop will always run 20 times, but when I inspect the application with VS2012 Analyser it tells me, it performs poor.

enter image description here

Can someone tell me how to refactor this with a more fast solution. I've read about predicates, but I'm not able to get them right.

Upvotes: 0

Views: 91

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1503899

Well, it looks to me like minuteAverage.Key.Subtract(new TimeSpan(0, i, 0)) doesn't depend on anything within the loop. So extract that:

var target = minuteAverage.Key.Subtract(new TimeSpan(0, i, 0));
var avrPrefMinute = d_averagesPerMinute.Where(n => n.Key == target);

Of course, if d_averagesPerMinute is a Dictionary<DateTime, double> you can just do a lookup instead:

var target = minuteAverage.Key.Subtract(new TimeSpan(0, i, 0));
double result;
if (d_averagesPerMinute.TryGetValue(target, out result))
{
    // Use result
}
else
{
    // No result found
}

Also, I'd actually suggest that rather than

minuteAverage.Key.Subtract(new TimeSpan(0, i, 0))

you use

minuteAverage.Key.AddMinutes(-i);

That's clearer, in my view.

Upvotes: 1

Obsidian Phoenix
Obsidian Phoenix

Reputation: 4155

I would recommend that you perform the Subtraction in a variable prior to the where. This way you are performing that action only once, rather than on each where evaluation:

var key = minuteAverage.Key.Subtract(new TimeSpan(0, i, 0));
IEnumerable<KeyValuePair<DateTime, double>> avrPrefMinute = d_averagesPerMinute.Where(n => n.Key == key);

However, this is purely based on the details you provided. Without seeing the whole loop that this is part of, and details on exactly what performance you are seeing, it is difficult to give complete advice.

Upvotes: 1

Related Questions