如何最有效地测试,如果两个数组包含在C#相当于项目 [英] How to most efficiently test if two arrays contain equivalent items in C#

查看:160
本文介绍了如何最有效地测试,如果两个数组包含在C#相当于项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个数组,我想知道他们是否包含相同的项目。 等于(obj对象)不起作用,因为数组是引用类型。我已经张贴了我下面的尝试,但因为我敢肯定,这是一个共同的任务,我想知道是否有一个更好的测试。

 公共BOOL ContainsEquivalentSequence< T>(T []数组1,T []数组2)
    {
        布尔a1IsNullOrEmpty =的ReferenceEquals(数组1,NULL)|| array1.Length == 0;
        布尔a2IsNullOrEmpty =的ReferenceEquals(数组2,NULL)|| array2.Length == 0;
        如果(a1IsNullOrEmpty)返回a2IsNullOrEmpty;
        如果(a2IsNullOrEmpty || array1.Length = array2.Length!)返回false;
        的for(int i = 0; I< array1.Length;我++)
            如果(!等于(数组1 [I]中,数组2 [I]))
                返回false;
        返回true;
    }

更新 - System.Linq.Enumerable.SequenceEqual是不是更好

我反映的来源和它的不长执行循环之前比较。这是有道理的,因为该方法一般设计为的IEnumerable< T> ,而不是一个 T []

 公共静态布尔SequenceEqual< TSource>(这个IEnumerable的< TSource>首先,IEnumerable的< TSource>第二个,的IEqualityComparer< TSource>比较器)
    {
        如果(比较器== NULL)
        {
            比较器= EqualityComparer< TSource> .DEFAULT;
        }
        如果(第一== NULL)
        {
            扔Error.ArgumentNull(第一);
        }
        如果(二== NULL)
        {
            扔Error.ArgumentNull(第二);
        }
        使用(IEnumerator的< TSource>枚举= first.GetEnumerator())
        {
            使用(IEnumerator的< TSource> enumerator2 = second.GetEnumerator())
            {
                而(enumerator.MoveNext())
                {
                    如果(!enumerator2.MoveNext()||!comparer.Equals(enumerator.Current,enumerator2.Current))
                    {
                        返回false;
                    }
                }
                如果(enumerator2.MoveNext())
                {
                    返回false;
                }
            }
        }
        返回true;
    }


解决方案

我已经用做了一些测试,任何包含所有 SequenceEqual 然后,我选择了最好的3。

有不同输入不同的结果...

100大小的两个相同的数组: SequenceEqual 也较快

  [SequenceEqual:00:00:00.027] *
[ContainsEqSeq:00:00:00.046]
[并行:00:00:00.281]

1000大小的两个相同的数组: SequenceEqual 也较快

  [SequenceEqual:00:00:00.240] *
[ContainsEqSeq:00:00:00.3​​61]
[并行:00:00:00.491]

10000大小的两个相同的数组:并行也较快

  [SequenceEqual:00:00:02.357]
[ContainsEqSeq:00:00:03.341]
[并行:00:00:01.688] *

50000大小的两个相同的数组:并行踢屁股

  [SequenceEqual:00:00:11.824]
[ContainsEqSeq:00:00:17.206]
[并行:00:00:06.811] *

两个阵列,但有一点不同在位置200: SequenceEqual 也较快

  [SequenceEqual:00:00:00.050] *
[ContainsEqSeq:00:00:00.075]
[并行:00:00:00.3​​32]

两个阵列,但有一点不同位置0: ContainsEqSeq SequenceEqual 为快

  [SequenceEqual:00:00:00.002] *
[ContainsEqSeq:00:00:00.001] *
[并行:00:00:00.211]

两个阵列,但有一点不同位置999: SequenceEqual 也较快

  [SequenceEqual:00:00:00.237] *
[ContainsEqSeq:00:00:00.3​​30]
[并行:00:00:00.691]

两个阵列,但有一点不同的位置9999:并行踢屁股

  [SequenceEqual:00:00:02.386]
[ContainsEqSeq:00:00:03.417]
[并行:00:00:01.614] *

在code为 SequenceEqual

  a1.SequenceEqual(A2)

在code为 ContainsEqSeq 是你的方法。

在code为并行

 布尔a1IsNullOrEmpty =的ReferenceEquals(A1,NULL)|| a1.Length == 0;
布尔a2IsNullOrEmpty =的ReferenceEquals(A2,NULL)|| a2.Length == 0;
如果(a1IsNullOrEmpty)返回a2IsNullOrEmpty;
如果(a2IsNullOrEmpty || a1.Length = a2.Length!)返回false;VAR areEqual = TRUE;
Parallel.ForEach(A1,
    (I,S,X)=>
    {
        如果(A1 [X]!= A2 [X])
        {
            areEqual = FALSE;
            s.Stop();
        }
    });返回areEqual;

我要说的是最好的一个取决于你输入的是什么。

如果您将与巨大的阵列的工作(如10000+)我会说并行是最好的选择,它只有当上一开始就失去了差异

有关其他案件 SequenceEqual 可能是最好的一个,我只能用 INT [] 测试过,但我相信,它可以快速与复杂类型为好。

但请记住,结果将相应变化的输入。

I have two arrays and I want to know if they contain the same items. Equals(object obj) doesn't work because an array is a reference type. I have posted my attempt below, but since I'm sure this is a common task I'd like to know if there is a better test.

    public bool ContainsEquivalentSequence<T>(T[] array1, T[] array2)
    {
        bool a1IsNullOrEmpty = ReferenceEquals(array1, null) || array1.Length == 0;
        bool a2IsNullOrEmpty = ReferenceEquals(array2, null) || array2.Length == 0;
        if (a1IsNullOrEmpty) return a2IsNullOrEmpty;
        if (a2IsNullOrEmpty || array1.Length != array2.Length) return false;
        for (int i = 0; i < array1.Length; i++)
            if (!Equals(array1[i], array2[i]))
                return false;
        return true;
    }

Update - System.Linq.Enumerable.SequenceEqual is not better

I reflected the source and it does not compare the length prior to executing the loop. This makes sense since the method is designed generally for an IEnumerable<T>, not for a T[].

    public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
    {
        if (comparer == null)
        {
            comparer = EqualityComparer<TSource>.Default;
        }
        if (first == null)
        {
            throw Error.ArgumentNull("first");
        }
        if (second == null)
        {
            throw Error.ArgumentNull("second");
        }
        using (IEnumerator<TSource> enumerator = first.GetEnumerator())
        {
            using (IEnumerator<TSource> enumerator2 = second.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    if (!enumerator2.MoveNext() || !comparer.Equals(enumerator.Current, enumerator2.Current))
                    {
                        return false;
                    }
                }
                if (enumerator2.MoveNext())
                {
                    return false;
                }
            }
        }
        return true;
    }

解决方案

I've done some tests using Any, Contains, All and SequenceEqual then I picked the best 3.

There are different results for different inputs...

Two identical arrays of size 100: SequenceEqual was faster

[     SequenceEqual: 00:00:00.027   ]*
[     ContainsEqSeq: 00:00:00.046   ]
[          Parallel: 00:00:00.281   ]

Two identical arrays of size 1000: SequenceEqual was faster

[     SequenceEqual: 00:00:00.240   ]*
[     ContainsEqSeq: 00:00:00.361   ]
[          Parallel: 00:00:00.491   ]

Two identical arrays of size 10000: Parallel was faster

[     SequenceEqual: 00:00:02.357   ]
[     ContainsEqSeq: 00:00:03.341   ]
[          Parallel: 00:00:01.688   ]*

Two identical arrays of size 50000: Parallel kick ass

[     SequenceEqual: 00:00:11.824   ]
[     ContainsEqSeq: 00:00:17.206   ]
[          Parallel: 00:00:06.811   ]*

Two arrays with one difference at position 200: SequenceEqual was faster

[     SequenceEqual: 00:00:00.050   ]*
[     ContainsEqSeq: 00:00:00.075   ]
[          Parallel: 00:00:00.332   ]

Two arrays with one difference at position 0: ContainsEqSeq and SequenceEqual were faster

[     SequenceEqual: 00:00:00.002   ]*
[     ContainsEqSeq: 00:00:00.001   ]*
[          Parallel: 00:00:00.211   ]

Two arrays with one difference at position 999: SequenceEqual was faster

[     SequenceEqual: 00:00:00.237   ]*
[     ContainsEqSeq: 00:00:00.330   ]
[          Parallel: 00:00:00.691   ]

Two arrays with one difference at position 9999: Parallel kick ass

[     SequenceEqual: 00:00:02.386   ]
[     ContainsEqSeq: 00:00:03.417   ]
[          Parallel: 00:00:01.614   ]*

The code for SequenceEqual is

a1.SequenceEqual(a2)

The code for ContainsEqSeq is your method.

The code for Parallel is

bool a1IsNullOrEmpty = ReferenceEquals(a1, null) || a1.Length == 0;
bool a2IsNullOrEmpty = ReferenceEquals(a2, null) || a2.Length == 0;
if (a1IsNullOrEmpty) return a2IsNullOrEmpty;
if (a2IsNullOrEmpty || a1.Length != a2.Length) return false;

var areEqual = true;
Parallel.ForEach(a1,
    (i, s, x) =>
    {
        if (a1[x] != a2[x])
        {
            areEqual = false;
            s.Stop();
        }
    });

return areEqual;

I would say that the best one depends on what your input will be.

If you will work with huge arrays (like 10000+) I would say Parallel is the best choice, it only loses when there is a difference on the beginning.

For other cases SequenceEqual might be the best one, I only tested with int[], but I believe it can be fast with complex types as well.

But remember, results will vary accordingly to the input.

这篇关于如何最有效地测试,如果两个数组包含在C#相当于项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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