2

I'm trying to compare 2 byte array using pointers. I treat the byte arrays as int pointer to run things faster(compare 4 bytes together).

    public static bool DoBuffersEqual(byte[] first, byte[] second)
    {
        unsafe
        {
            fixed (byte* pfirst = first, psecond = second)
            {
                int* intfirst = (int*)pfirst;
                int* intsecond = (int*)psecond;

                for (int i = 0; i < first.Length / 4; i++)
                {
                    if ((intfirst + i) != (intsecond + i))
                        return false;
                }
            }
        }
        return true;
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        byte[] arr1 = new byte[4000];
        byte[] arr2 = new byte[4000];
        for (int i = 0; i < arr1.Length; i++)
        {
            arr1[i] = 100;
            arr2[i] = 100;
        }
        bool res = DoBuffersEqual(arr1, arr2);
        Console.WriteLine(res);
    }

For some reason i'm getting False result after calling this function...

Does anybody have any idea what's wrong here?

Thanks in advance!

6
  • Possible duplicate of Checking equality for two byte arrays Commented Apr 3, 2017 at 11:14
  • 3
    You're comparing the pointers, not the pointed to values. So : if (*(intfirst + i) != *(intsecond + i)) Commented Apr 3, 2017 at 11:16
  • 1
    You don't dereference your pointers so you are comparing pointers not values they point to. Commented Apr 3, 2017 at 11:17
  • @spender ooops...your right... haha thanks Commented Apr 3, 2017 at 11:17
  • Something for you to consider: this would be a great fit for Vector<byte> and SIMD, so that on modern CPUs you can compare much wider chunks at a time (32 bytes = 256 bits on my AVX i7). The tricky bit is loading the values - Unsafe.Read<T> is your friend there. Also, remember to check Vector.IsHardwareAccelerated - if it is false, don't use it; and check Vector<byte>.Count to check the local hardware-specific SIMD support to know your stride size. And even if you don't like SIMD: you can still have the op-count by using long rather than int. Commented Apr 3, 2017 at 11:20

1 Answer 1

2

As other comments have already stated, the problem is that you are comparing pointers, not values. The correct code should be:

if (*(intfirst + i) != *(intsecond + i))

But I'd like to point out a deeper issues in your code.

  • If the input byte arrays have lengths that don't align with 4 (first.Length % 4 != 0) you will get false positives because you'll be essentially swallowing all misaligned items:

    {1, 2, 3, 4, 5}
    {1, 2, 3, 4, 7}
    

    Will return true when they are obviously not the same.

  • You should be checking, before anything else, that both arrays have the same length and bailing out fast if they don't. You'll run into all kind of issues otherwise.

    {1, 2, 3, 0}
    {1, 2, 3}
    

    Will also return true when it shoudn't.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.