Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ IEnumerable<T> Memory Structure

Tags:

c#

memory

linq

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?

like image 476
Persistence Avatar asked Apr 26 '17 08:04

Persistence


2 Answers

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.

like image 153
Damien_The_Unbeliever Avatar answered Sep 23 '22 23:09

Damien_The_Unbeliever


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.

like image 45
Patrick Hofman Avatar answered Sep 25 '22 23:09

Patrick Hofman