代码之家  ›  专栏  ›  技术社区  ›  Moberg

了解扩展元素at(index)

  •  5
  • Moberg  · 技术社区  · 16 年前

    考虑此代码:

    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更快的时间时(数组为0.0002,而IEnumerable为0.59s)。

    据我所知,extention方法elementat()具有签名

    public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)
    

    因为“源”是一个IEnumerable,所以执行的逻辑是类似的——与我看到的直接访问数组的位置相反。

    有人能解释一下吗:)

    2 回复  |  直到 9 年前
        1
  •  5
  •   Jon Skeet    16 年前

    这是在执行的优化 执行时间 . 虽然调用没有过载,但它可以检查(使用 is as )源是否实际是 IList<T> . 如果是的话,它可以直接转到正确的元素。

    其他各种电话都会这样做-值得注意 Count() 这是优化的 ICollection<T> 和(从.NET 4开始)非能量的 ICollection 接口。

    扩展方法的缺点之一是所有这些优化都必须由实现本身执行——类型不能覆盖任何东西来“选择加入”来优化扩展方法。这意味着最初的实现者必须知道所有的优化:(

        2
  •  12
  •   SLaks    16 年前

    打电话 ElementAt 关于一个 IEnumerable<T> 将循环遍历这些项,直到达到所需的索引。(O(N)操作)

    打电话 要素 关于一个 IList<T> (例如数组)将使用 ILIST & T;T & GT; 的索引器,以立即获取所需的索引。(O(1)操作)