考虑下面的代码:
int size = 100 * 1000 * 1000;
var emu = Enumerable.Range(0, size);
var arr = Enumerable.Range(0, size).ToArray();当我调用emu.ElementAt(size-10)和arr.ElementAt(size-10)并测量时间时,arr要快得多(与IEnumerable 0.59s相比,数组为0.0002s )。
据我所知,扩展方法ElementAt()具有如下签名
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)由于“源”是一个IEnumerable,所以执行的逻辑将类似于我所看到的直接访问数组的逻辑。
谁能解释一下这个:)
发布于 2010-07-05 22:12:52
这是在执行时执行的优化。尽管调用没有重载,但它能够检查(使用is或as)源是否实际上是一个IList<T>。如果是,它可以直接转到正确的元素。
许多其他调用都会这样做-值得注意的是Count(),它针对ICollection<T>和(从.NET 4开始)非通用ICollection接口进行了优化。
扩展方法的缺点之一是,所有这些优化都必须由实现本身执行-类型不能覆盖任何东西来“选择”优化扩展方法。这意味着优化必须由原始实现者知道:(
发布于 2010-07-05 22:05:56
在IEnumerable<T>上调用ElementAt将遍历这些项,直到到达所需的索引。( O(n)运算)
在IList<T> (如数组)上调用ElementAt将使用IList<T>的索引器立即获得所需的索引( O(1)操作)
https://stackoverflow.com/questions/3180091
复制相似问题