LINQ IEnumerable <T> Memory Structure
So, I understand that the most common collection C#
implement the interface IEnumerable<T>
: List<T>
, T[]
and Dictionary<TKey,TVal>
all of them do.
However, when you run a LINQ query like:
myCol.Where(myBoolMethod);
You are returning data as an unknown type that implements IEnumerable<T>
.
Hence, I'm wondering how this data is stored until you convert it to a more useful format with .ToList()
, .ToArray()
etc.
Does it stay in the source type? Is it stored in a pseudo-array? Is it some combination of the above?
Also, is there any reason why converting to one type IEnumerable<T>
would ALWAYS be faster than converting to another, i.e. where is myCol.Where(myBoolMethod).ToArray()
always faster than myCol.Where(myBoolMethod).ToList()
, regardless of the data types used
source to share
It is not saved. It represents the ability to retrieve data at a later point in time, but the data itself is still hidden in the original collections from which the linq query was composed. (And any logic that exists to create new values โโfrom expressions)
This is why there are all sorts of warnings against storing these results without using a method ToXxx
if there is a chance that you will actually call the query multiple times.
source to share
Does it stay in the source type? Is it stored in a pseudo-array? Is it some combination of the above?
Most LINQ extension methods will loop through the source each time you access the received one IEnumerable<T>
(this is called deferred execution). Results are usually not saved to an intermediate source.
is there a reason why converting to one type IEnumerable would ALWAYS be faster than converting to another from
Yes, call ToArray
or ToList
will execute the enum and materialize it. If you don't use the returned IEnumerable<T>
one it won't get implemented. The performance impact is around 0.
source to share
In fact WhereEnumerableIterator
(if myCol IEnumerable
).
http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,119
It only contains a link to the initial myCol
and a link to Func<T, bool>
.
If myCol
is a different type, it might be a different, more optimized LINQ iterator.
source to share