C# LINQ, does it cache queries?

puffpio

Golden Member
Dec 21, 1999
1,664
0
0
Say I have this:

// ------------------------
IEnumerable<myType> foo = ....;

// grouping my results by day, then ordering the groups from oldest to newest
var fooOrderedGrouping = foo.GroupBy(f => f.DateTime.Date).OrderBy(g => g.Key);

DateTime firstDay = fooOrderedGrouping.First().Key;
DateTime lastDay = fooOrderedGrouping.Last().Key;

int firstDayCount = fooOrderedGrouping.First().Count();
int lastDayCount = fooOrderedGrouping.Last().Count();

// -------------------------

Are the results of First() and Last() cached? or is it reexecuted every time?
Because I could restructure it like this:

// ----------------------------

var firstGroup = fooOrderedGrouping.First();
var lastGroup = fooOrderedGrouping.Last();

DateTime firstDay = firstGroup.Key;
DateTime lastDay = lastGroup.Key;

int firstDayCount = firstGroup.Count();
int lastDayCount = lastGroup.Count();

// ------------------------------


which, to me, seems like the First() and Last() methods will only be hit once
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
This question really has nothing to do with caching queries, and only a marginal relationship to LINQ. When you execute the Enumerable.GroupBy() extension method it returns IEnumerable<IGrouping<TKey, TSource>>. That enumerable collection captures the grouped state of the input data in a list of objects that implement IGrouping. So when you call First() or Next() on the results from GroupBy(), you're returning the head or advancing the current reference (to an IGrouping implementor) from a generic collection.

That's all. So the real question is how efficient are these operations on a generic collection? According to reflector the interfaces in question are probably implemented by Enumerable and GroupedEnumerable, but that's almost beside the point. We can assume that Next(), which is a forward traversal of a list, is extremely efficient. It's probably on the same order as an access of an array, i.e. O(1). Finding the head of the list is also extremely efficient, since it has to be stored in a reference somewhere, so this should also be O(1).

In other words, I wouldn't worry about it :).