0

私が@stackOverFlowで見ていた2つの方法があります、私は他のどこかにそれらのさらに多くがあるかもしれないと思います、私の質問は賢明な最高のパフォーマンスです

そして2番目の質問、私はこのコードを持っています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;
     } 

そして、私はこれを実装できませんでした、workaroud iguessを理解していませんでした私は間違った構文を使用したので、byet[]ファイルを読み取るためのヘルパーメソッドがある場合

    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()この2番目のコードで必要なパラメーターのセットを使用して、どのように作成するのですか?

    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;
 } 

この最後の構文を実装するための正しい構文は何ですか、そして2つを比較するより速い方法がある場合

 byte[] 

それらが同じ長さであることを知っています。そして、これについてどう思いますか?

再編集: ここに画像の説明を入力してください

1つ目は安全でないコードです。

2番目は私が書いた最初のコードです(bool ArraysEqual()

そして3番目は

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であなたのランダムの実装を投稿できますか?

ここに画像の説明を入力してください

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 に答える