SequenceEqual有什么好处? [英] What is the benefit of SequenceEqual?

查看:93
本文介绍了SequenceEqual有什么好处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在for循环中对SequenceEqual和元素比较进行了比较.

I did a comparison between SequenceEqual and element comparison in for loop.

static void Main(string[] args)
    {
        //var myList = new List<short>();
        //var anotherList = new List<short>();
        var myList = new short[2000000];
        var anotherList = new short[2000000];

        for (int i = 0; i < 2000000; i++)
        {
            //myList.Add(5);
            //anotherList.Add(5);
            myList[i] = 5;
            anotherList[i] = 5;
        }

        var watch = System.Diagnostics.Stopwatch.StartNew();
        //for (int i = 0; i < 2000000; i++)
        //{
        //    if (myList[i] != anotherList[i])
        //        break;
        //}
        bool isEqual = myList.SequenceEqual(anotherList);
        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;
        Console.WriteLine(elapsedMs);
        Console.Read();
    }

在myList和anotherList是数组的情况下,直接比较执行4 ms,SequenceEqual执行21ms.当myList和anotherList是列表时,直接比较执行13 ms,SequenceEqual执行30 ms.

In the case when myList and anotherList are arrays, the direct comparison executes for 4 ms, SequenceEqual executes for 21ms. When myList and anotherList are lists, the direct comparison executes for 13 ms, SequenceEqual for 30 ms.

如果速度慢得多,是否有使用时会有益的情况?我只能想到其中之一,它节省了几行代码.

If it is so much slower, are there cases when it would be beneficial to use? I can only think of one, that it saves several lines of code.

推荐答案

更具体地研究List,似乎很多放缓源于SequenceEqual中使用通用IEnumerator的通用实现. List特定版本的速度,是两倍多的速度.但是,如果仍然要测试List,则最好直接在for循环中进行编码,而不要使用枚举.

Looking into especially Lists more specifically, it seems a lot of slow down comes from the generic implementation in SequenceEqual using the generic IEnumerator instead of the List specific version, which is more than twice as fast. However, if you are going to test for List anyway, might as well code in the for loop directly instead of using enumeration.

请注意,对IList的测试要慢得多,因为List没有实现IList<T>.operator[],这意味着它将调用IList.operator[]并返回object并导致装箱.

Note that testing for IList is a lot slower, because List doesn't implement IList<T>.operator[] which means it calls IList.operator[] which returns object and causes boxing.

我还特例Array,因为IList界面比直接访问要慢得多,这也是由于装箱造成的.

I also special case Arrays as the IList interface is much slower than direct access, again due to boxing.

当然,利用已知类型的高速CountLength可以使不相等的长度比较比SequenceEqual快得多. OTOH,如果前两个元素不相等,则SequenceEqual可能比我的函数要快.

Of course, taking advantage of the high speed Count or Length available for known types makes unequal length comparisons tremendously faster than SequenceEqual. OTOH, if the first two elements are unequal, SequenceEqual can be faster than my function.

这是我的LocalSequenceEqual:

public static bool LocalSequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer = null) {
    if (first is ICollection<TSource> fc && second is ICollection<TSource> sc)
        if (fc.Count != sc.Count)
            return false;

    var cmp = comparer ?? EqualityComparer<TSource>.Default;

    if (first is TSource[] fa && second is TSource[] sa) {
        for (int j1 = 0; j1 < fa.Length; ++j1)
            if (!cmp.Equals(fa[j1], sa[j1]))
                return false;
        return true;
    }

    if (first is List<TSource> fl && second is List<TSource> sl) {
        for (int j1 = 0; j1 < fl.Count; ++j1) {
            if (!cmp.Equals(fl[j1], sl[j1]))
                return false;
        }
        return true;
    }

    using (var e1 = first.GetEnumerator()) {
        using (var e2 = second.GetEnumerator()) {
            while (e1.MoveNext()) {
                if (!(e2.MoveNext() && cmp.Equals(e1.Current, e2.Current)))
                    return false;
            }
            if (e2.MoveNext())
                return false;
        }
    }
    return true;
}

这篇关于SequenceEqual有什么好处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆