为什么自定义Where()实现比LINQ Where()慢

时间:2018-04-17 13:36:58

标签: c# performance linq

我写了Where()实现:

    public static IEnumerable<TSource> MyWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
        using (var enumerator = source.GetEnumerator())
        {
            if (!enumerator.MoveNext()) throw new InvalidOperationException("Sequence contains no elements");            
            do
            {
                var candidate = enumerator.Current;
                if (predicate(candidate))
                    yield return candidate;
            }
            while (enumerator.MoveNext());
        }
    }

并将其性能与LINQ Where()进行比较:

        var data = new int[1000000];
        for (int i = 0; i < data.Length; i++)
            data[i] = int.MaxValue;
        Stopwatch stopwatch = new Stopwatch();

        // My Where() test
        stopwatch.Start();
        var res2 = data.MyWhere(x => x == int.MaxValue).ToList();
        stopwatch.Stop();
        Console.WriteLine(stopwatch.ElapsedTicks);

        stopwatch.Reset();

        // LINQ Where() test
        stopwatch.Start();
        var res = data.Where(x => x == int.MaxValue).ToList();
        stopwatch.Stop();
        Console.WriteLine(stopwatch.ElapsedTicks);

并得到以下结果:

124487
 50827

帮助我理解为什么MyWhere()实施太慢了?我究竟做错了什么?感谢。

1 个答案:

答案 0 :(得分:14)

自己检查WhereArrayIterator

的参考来源

迭代器专门用于某些具体类型,如类型化数组和if (source is Iterator<TSource>) return ((Iterator<TSource>)source).Where(predicate); if (source is TSource[]) return new WhereArrayIterator<TSource>((TSource[])source, predicate); if (source is List<TSource>) return new WhereListIterator<TSource>((List<TSource>)source, predicate); return new WhereEnumerableIterator<TSource>(source, predicate); ,它们在访问某些给定的n=O(g(n))元素时会对效率产生积极影响。

例如,请参阅Enumerable.Where的这一部分:

> m=(1,2,3 ... ) --> n=O(g(n^m)) ..