0

我在看@stackOverFlow 有两种方法,我想其他地方可能还有更多,我的问题是最好的性能是什么

第二个问题,我有这个代码只需要几个byte[]

     bool ArraysEqual(byte[] a1, byte[] a2)
     {
         if (a1 == a2)
             return true;
          if (a1 == null || a2 == null)
             return false;
          if (a1.Length != a2.Length)
             return false;
          for (int i = 0; i < a1.Length; i++)
         {
             if (a1[i] != a2[i])
                 return false;
         }
         return true;
     } 

而且我无法实现这个,我不知道我使用了错误的语法,所以如果我有一个辅助方法来读取字节 [] 文件

    public byte[] readByteArr(string FilePath)
    {
       return File.ReadAllBytes(FilePath);

    } 

i could make it simply via 



void CompareIt(){

byte[] src = readByteArr(S.bar);
byte[] dest = readByteArr(D.bar);
if(ArraysEqual(src, dest))
DoSomthing
}

我该如何制作CompareIt(),在第二个代码中需要设置参数集,我也尝试实现,只是为了检查哪个执行beeter

    bool ArraysEqual<T>(T[] a1, T[] a2)
    {
     if (ReferenceEquals(a1,a2))
         return true;
      if (a1 == null || a2 == null)
         return false;
      if (a1.Length != a2.Length)
         return false;
      EqualityComparer<T> comparer = EqualityComparer<T>.Default;
     for (int i = 0; i < a1.Length; i++)
     {
         if (!comparer.Equals(a1[i], a2[i]))
            return false;
     }
     return true;
 } 

实现最后一个的正确语法是什么,以及是否有更快的方法来比较两者

 byte[] 

知道它们的长度相同。你怎么看?

重新编辑: 在此处输入图像描述

首先是不安全的代码。

第二个是我写的第一个代码(bool ArraysEqual()

第三是

myArray.SequenceEqual(otherArray); 

现在好好看看这个 请允许我宣布,获胜者是:

[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int memcmp(byte[] b1, byte[] b2, long count);

static bool ByteArrayCompare(byte[] b1, byte[] b2)
{
    // Validate buffers are the same length.     
    // This also ensures that the count does not exceed the length of either buffer.
    return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;
}

@混乱 。你能用我的 Pinvoke 发布你的 Random 的实现吗?

在此处输入图像描述

4

2 回答 2

4

如果您使用 .NET > 3.0:

myArray.SequenceEqual(otherArray);

MSDN - Enumerable.SequenceEqual

如果您想使用自定义的“EqualityComparer”,您可以使用MSDN - Enumerable.SequenceEqual 和 IEqualityComparer

;-)

于 2012-08-31T23:24:01.747 回答
1
  • 最佳:数据是随机的
  • 最差:数据相等
  • 平均值:最好情况和最坏情况的平均值

真正的测试将包括数据几乎相等的情况,但我们在这里看到的平均值让我们很好地了解如果您的数据几乎可以是任何东西,这些事情将如何执行。最好的算法实际上取决于您期望什么样的数据。请注意,单线程安全方法在最好的情况下最快,但在最坏的情况下最慢。

表现

class Program
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern int memcmp(byte[] b1, byte[] b2, long count);

    static bool AreEqualNative(byte[] a, byte[] b)
    {
        if (a == b)
            return true;
        if (a == null || b == null)
            return false;
        if (a.Length != b.Length)
            return false;
        return memcmp(a, b, a.Length) == 0;
    }

    static bool AreEqualSafe(byte[] a1, byte[] a2)
    {
        if (a1 == a2)
            return true;
        if (a1 == null || a2 == null)
            return false;
        if (a1.Length != a2.Length)
            return false;
        for (int i = 0; i < a1.Length; i++)
        {
            if (a1[i] != a2[i])
                return false;
        }
        return true;
    }

    static bool AreEqualSafeParallel(byte[] a1, byte[] a2, int start, int length)
    {
        for (int i = start; i < length; i++)
        {
            if (a1[i] != a2[i])
                return false;
        }
        return true;
    }

    static bool AreEqualSafeParallel(byte[] a, byte[] b)
    {
        if (a == b)
            return true;
        if (a == null || b == null)
            return false;
        if (a.Length != b.Length)
            return false;
        bool b1 = false;
        bool b2 = false;
        bool b3 = false;
        bool b4 = false;
        int quar = a.Length / 4;
        Parallel.Invoke(
            () => b1 = AreEqualSafeParallel(a, b, 0, quar),
            () => b2 = AreEqualSafeParallel(a, b, quar, quar),
            () => b3 = AreEqualSafeParallel(a, b, quar * 2, quar),
            () => b4 = AreEqualSafeParallel(a, b, quar * 3, a.Length)
        );
        return b1 && b2 && b3 && b4;
    }

    static unsafe bool AreEqualUnsafe(byte[] a, byte[] b)
    {
        if (a == b)
            return true;
        if (a == null || b == null)
            return false;
        if (a.Length != b.Length)
            return false;
        int len = a.Length / 8;
        if (len > 0)
        {
            fixed (byte* ap = &a[0])
            fixed (byte* bp = &b[0])
            {
                long* apl = (long*)ap;
                long* bpl = (long*)bp;

                for (int i = 0; i < len; i++)
                {
                    if (apl[i] != bpl[i])
                        return false;
                }
            }
        }
        int rem = a.Length % 8;
        if (rem > 0)
        {
            for (int i = a.Length - rem; i < a.Length; i++)
            {
                if (a[i] != b[i])
                    return false;
            }
        }
        return true;
    }

    static unsafe bool AreEqualUnsafeParallel(byte[] a, byte[] b, int start, int length)
    {
        int len = length / 8;
        if (len > 0)
        {
            fixed (byte* ap = &a[0])
            fixed (byte* bp = &b[0])
            {
                long* apl = (long*)ap;
                long* bpl = (long*)bp;

                for (int i = start; i < len; i++)
                {
                    if (apl[i] != bpl[i])
                        return false;
                }
            }
        }
        int rem = length % 8;
        if (rem > 0)
        {
            for (int i = length - rem; i < length; i++)
            {
                if (a[i] != b[i])
                    return false;
            }
        }
        return true;
    }

    static unsafe bool AreEqualUnsafeParallel(byte[] a, byte[] b)
    {
        if (a == b)
            return true;
        if (a == null || b == null)
            return false;
        if (a.Length != b.Length)
            return false;
        bool b1 = false;
        bool b2 = false;
        bool b3 = false;
        bool b4 = false;
        int quar = a.Length / 4;
        Parallel.Invoke(
            () => b1 = AreEqualUnsafeParallel(a, b, 0, quar),
            () => b2 = AreEqualUnsafeParallel(a, b, quar, quar),
            () => b3 = AreEqualUnsafeParallel(a, b, quar * 2, quar),
            () => b4 = AreEqualUnsafeParallel(a, b, quar * 3, a.Length)
        );
        return b1 && b2 && b3 && b4;
    }

    static readonly Random _rnd = new Random();
    static void SpeedTest(string name, int length, int iterations, Func<byte[], byte[], bool> func)
    {
        var a = new byte[length];
        var b = new byte[length];

        _rnd.NextBytes(a);
        _rnd.NextBytes(b);

        var sw1 = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            func(a, b);
        }
        sw1.Stop();

        var c = new byte[length];
        var d = new byte[length];

        var sw2 = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            func(c, d);
        }
        sw2.Stop();

        Console.WriteLine(name + ":");
        Console.WriteLine("  Best: " + sw1.Elapsed);
        Console.WriteLine("  Worst: " + sw2.Elapsed);
        Console.WriteLine("  Average: " + TimeSpan.FromTicks((sw1.Elapsed.Ticks + sw2.Elapsed.Ticks) / 2));
    }

    static void Test(bool shouldBeEqual, byte[] a, byte[] b)
    {
        if (shouldBeEqual != AreEqualSafe(a, b))
            throw new Exception();
        if (shouldBeEqual != AreEqualSafeParallel(a, b))
            throw new Exception();
        if (shouldBeEqual != AreEqualUnsafe(a, b))
            throw new Exception();
        if (shouldBeEqual != AreEqualUnsafeParallel(a, b))
            throw new Exception();
        if (shouldBeEqual != AreEqualNative(a, b))
            throw new Exception();
    }

    static void VerifyCorrectness()
    {
        Test(true,
        new byte[] { 1, 2, 3, 4, 5, 6, 7 },
        new byte[] { 1, 2, 3, 4, 5, 6, 7 });

        Test(true,
        new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
        new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });

        Test(false,
        new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
        new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12 });
    }


    static void Main(string[] args)
    {
        VerifyCorrectness();

        var length = 1000000;
        var iterations = 10000;

        Console.WriteLine("Length:");
        Console.WriteLine("  " + length.ToString("N"));
        Console.WriteLine("Iterations:");
        Console.WriteLine("  " + iterations.ToString("N"));

        SpeedTest("Safe", length, iterations, AreEqualSafe);
        SpeedTest("SafeParallel", length, iterations, AreEqualSafeParallel);
        SpeedTest("Unsafe", length, iterations, AreEqualUnsafe);
        SpeedTest("UnsafeParallel", length, iterations, AreEqualUnsafeParallel);
        SpeedTest("Native", length, iterations, AreEqualNative);

        Console.ReadLine();
    }
}
于 2012-08-31T23:33:35.713 回答