Сравнение массива байтов C#

наконец блок ценен для чистки любых ресурсов, выделенных в блоке попытки, а также выполнении любого кода, который должен выполниться, даже если существует исключение. Управление всегда передается к наконец блок независимо от того, как блок попытки выходит.

14
задан psubsee2003 29 June 2015 в 00:07
поделиться

4 ответа

Ну, вы могли бы использовать:

public static bool ByteArraysEqual(byte[] b1, byte[] b2)
{
    if (b1 == b2) return true;
    if (b1 == null || b2 == null) return false;
    if (b1.Length != b2.Length) return false;
    for (int i=0; i < b1.Length; i++)
    {
        if (b1[i] != b2[i]) return false;
    }
    return true;
}

(Обычно я использую фигурные скобки для всего, но я решил поэкспериментировать с этим стилем макета только для разнообразия ...)

Это имеет несколько оптимизаций, которые SequenceEqual не может (или не выполняет) выполнить - например, предварительная проверка длины. Прямой доступ к массиву также будет немного более эффективным, чем использование перечислителя.

По общему признанию, в большинстве случаев это вряд ли будет иметь существенное значение ...

Вы можете , возможно, сделать это быстрее в неуправляемом коде заставляя его сравнивать 32 или 64 бита за раз вместо 8 - но я не хотел бы кодировать это на лету.

37
ответ дан 1 December 2019 в 05:51
поделиться

Вы можете использовать метод SequenceEqual :

bool areEqual = firstArray.SequenceEqual(secondArray);

Как упоминалось в комментариях, SequenceEqual требует .NET 3.5 (или LINQBridge , если вы используете VS2008 и ориентируетесь на более раннюю версию платформы).

26
ответ дан 1 December 2019 в 05:51
поделиться

Джон упомянул одновременное сравнение нескольких байтов с использованием небезопасного кода, поэтому мне пришлось попробовать:

public unsafe bool ByteArraysEqual(byte[] b1, byte[] b2) {
   if (b1 == b2) return true;
   if (b1 == null || b2 == null) return false;
   if (b1.Length != b2.Length) return false;
   int len = b1.Length;
   fixed (byte* p1 = b1, p2 = b2) {
      int* i1 = (int*)p1;
      int* i2 = (int*)p2;
      while (len >= 4) {
         if (*i1 != *i2) return false;
         i1++;
         i2++;
         len -= 4;
      }
      byte* c1 = (byte*)i1;
      byte* c2 = (byte*)i2;
      while (len > 0) {
         if (*c1 != *c2) return false;
         c1++;
         c2++;
         len--;
      }
   }
   return true;
}

Безопасный код довольно оптимизирован (компилятор знает, что это не обязательно проверьте, например, границы индекса), поэтому я не ожидал, что небезопасный код будет намного быстрее. Любая существенная разница возникнет из-за возможности одновременного сравнения нескольких байтов.

5
ответ дан 1 December 2019 в 05:51
поделиться

Если вы хотите, чтобы это было очень быстро, вы можете использовать небезопасный код (что не всегда возможно):

    public static bool ArraysEqual(byte[] b1, byte[] b2)
    {
        unsafe
        {
            if (b1.Length != b2.Length)
                return false;

            int n = b1.Length;

            fixed (byte *p1 = b1, p2 = b2)
            {
                byte *ptr1 = p1;
                byte *ptr2 = p2;

                while (n-- > 0)
                {
                    if (*ptr1++ != *ptr2++)
                        return false;
                }
            }

            return true;
        }
    }
2
ответ дан 1 December 2019 в 05:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: