ScottishTapWater
ScottishTapWater

Reputation: 4806

LINQ IEnumerable<T> Memory Structure

So I understand that the most common collections in C# all implement the IEnumerable<T> interface: List<T>, T[] and Dictionary<TKey,TVal> all do this.

However, when you run a LINQ query such as:

myCol.Where(myBoolMethod);

You are returned data as an unknown type that implements IEnumerable<T>.

Consequently, I'm wondering how this data is actually stored until you convert it into a more useful format through .ToList(), .ToArray() etc.

Does it remain in the type of the source? Does it get stored in a pseudo-array? Is it some sort of combination of the above?

Further to this, is there any reason why converting to one type of IEnumerable<T> will ALWAYS be quicker than converting to a different one from - ie where myCol.Where(myBoolMethod).ToArray() is always quicker than myCol.Where(myBoolMethod).ToList() regardless of the data types involved?

Upvotes: 5

Views: 611

Answers (4)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34199

When you do myCol.Where(myBoolMethod) the data is actually not being enumerated. It is not stored in array or whatever else, you just get the enumerator which lets you enumerate this collection.

When you do .ToArray() it actually uses enumerator to create a new array.

Upvotes: 0

Patrick Hofman
Patrick Hofman

Reputation: 156978

Does it remain in the type of the source? Does it get stored in a pseudo-array? Is it some sort of combination of the above?

Most LINQ extension methods will loop over the source every time you access the resulting IEnumerable<T> (it's called deferred execution). The results are generally not stored in an intermediate source.

is there any reason why converting to one type of IEnumerable will ALWAYS be quicker than converting to a different one from

Yes, calling ToArray or ToList will execute the enumerable and materialize it. If you don't use the returned IEnumerable<T>, it will not materialize it. The performance impact is about 0.

Upvotes: 3

Leotsarev
Leotsarev

Reputation: 1062

That's actually WhereEnumerableIterator (if myCol is IEnumerable). http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,119

It contains just reference to initial myCol and reference to Func<T, bool>.

If mycol is another type, it could be another, more optimized LINQ iterator.

Upvotes: 0

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239704

It's not stored. It represents the ability to obtain the data at a later point in time, but the data itself is still lurking in the original collection(s) from which the linq query has been composed. (And any logic that exists to create new values from expressions)

This is why there are all kinds of admonitions against storing these results without using a ToXxx method if there's any possibility that you'll actually cause the query to execute multiple times.

Upvotes: 5

Related Questions