简体   繁体   English

LINQ IEnumerable <T> 记忆结构

[英]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. 所以我理解C#最常见的集合都实现了IEnumerable<T>接口: List<T>T[]Dictionary<TKey,TVal>都是这样做的。

However, when you run a LINQ query such as: 但是,当您运行LINQ查询时,例如:

myCol.Where(myBoolMethod);

You are returned data as an unknown type that implements IEnumerable<T> . 您将返回的数据作为实现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. 因此,我想知道这些数据是如何实际存储的,直到通过.ToList() .ToArray()等将其转换为更有用的格式。

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? 除此之外,有没有理由为什么转换为一种类型的IEnumerable<T>总是比转换为另一种更快 - 即myCol.Where(myBoolMethod).ToArray()总是比myCol.Where(myBoolMethod).ToList()更快myCol.Where(myBoolMethod).ToList()无论涉及哪种数据类型?

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. 它表示在稍后的时间点获取数据的能力,但数据本身仍然潜伏在组成linq查询的原始集合中。 (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. 这就是为什么在没有使用ToXxx方法的情况下存在各种警告来反对存储这些结果,如果你有可能实际上导致查询多次执行。

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). 每次访问生成的IEnumerable<T> (它称为延迟执行)时,大多数LINQ扩展方法都会遍历源代码。 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 是否有任何理由为什么转换为一种类型的IEnumerable总是比转换为另一种更快

Yes, calling ToArray or ToList will execute the enumerable and materialize it. 是的,调用ToArrayToList执行可枚举并实现它。 If you don't use the returned IEnumerable<T> , it will not materialize it. 如果您不使用返回的IEnumerable<T> ,它将不会实现它。 The performance impact is about 0. 性能影响大约为0。

That's actually WhereEnumerableIterator (if myCol is IEnumerable ). 那实际上是WhereEnumerableIterator (如果myCol是IEnumerable )。 http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,119 http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,119

It contains just reference to initial myCol and reference to Func<T, bool> . 它只包含对初始myCol引用和对Func<T, bool>引用。

If mycol is another type, it could be another, more optimized LINQ iterator. 如果mycol是另一种类型,它可能是另一个更优化的LINQ迭代器。

When you do myCol.Where(myBoolMethod) the data is actually not being enumerated. 当你执行myCol.Where(myBoolMethod) ,实际上没有枚举数据。 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. 当你执行.ToArray()它实际上使用枚举器来创建一个新数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM