Сравнение двухбайтовых массивов в .NET

в качестве другого примера, рассмотрим класс автомобилей, это будет хорошим использованием композиции, автомобиль будет иметь «двигатель», коробку передач, шины, сиденья и т. д. Он не будет распространять ни один из этих классов.

495
задан Community 23 May 2017 в 12:34
поделиться

9 ответов

Можно использовать Счетный. Метод SequenceEqual .

using System;
using System.Linq;
...
var a1 = new int[] { 1, 2, 3};
var a2 = new int[] { 1, 2, 3};
var a3 = new int[] { 1, 2, 4};
var x = a1.SequenceEqual(a2); // true
var y = a1.SequenceEqual(a3); // false

, Если Вы не можете использовать.NET 3.5 по некоторым причинам, Ваш метод в порядке.
Compiler\run-разовая среда оптимизирует Ваш цикл, таким образом, Вы не должны будете волноваться о производительности.

573
ответ дан aku 23 May 2017 в 12:34
поделиться

Извините, при поиске управляемого способа, которым Вы уже делаете его правильно и к моему знанию существует не создано в методе в BCL для того, чтобы сделать это.

необходимо добавить некоторые начальные пустые проверки и затем просто снова использовать его как будто это где в BCL.

0
ответ дан Markus Olsson 23 May 2017 в 12:34
поделиться

Если Вы не настроены против выполнения его, можно импортировать блок J# "vjslib.dll" и использовать Arrays.equals (байт [], байт []) метод ...

не обвиняют меня, если кто-то смеется над Вами хотя...

<час>

РЕДАКТИРОВАНИЕ: Поскольку, что мало это стоит, я использовал Отражатель для разборки кода для этого, и здесь - то, на что это похоже:

public static bool equals(sbyte[] a1, sbyte[] a2)
{
  if (a1 == a2)
  {
    return true;
  }
  if ((a1 != null) && (a2 != null))
  {
    if (a1.Length != a2.Length)
    {
      return false;
    }
    for (int i = 0; i < a1.Length; i++)
    {
      if (a1[i] != a2[i])
      {
        return false;
      }
    }
    return true;
  }
  return false;
}
26
ответ дан Jason Bunting 23 May 2017 в 12:34
поделиться

Я использовал бы небезопасный код и работал бы for цикл, сравнивающий указатели Int32.

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

6
ответ дан Peter Mortensen 23 May 2017 в 12:34
поделиться

.NET 3.5 и новее имеют новый открытый тип, System.Data.Linq.Binary , который инкапсулирует байт [] . Он реализует IEquatable , который (в действительности) сравнивает два байтовых массива. Обратите внимание, что System.Data.Linq.Binary также имеет оператор неявного преобразования из байта [] .

Документация MSDN: System.Data.Linq.Binary

Отражатель декомпиляции метода Equals:

private bool EqualsTo(Binary binary)
{
    if (this != binary)
    {
        if (binary == null)
        {
            return false;
        }
        if (this.bytes.Length != binary.bytes.Length)
        {
            return false;
        }
        if (this.hashCode != binary.hashCode)
        {
            return false;
        }
        int index = 0;
        int length = this.bytes.Length;
        while (index < length)
        {
            if (this.bytes[index] != binary.bytes[index])
            {
                return false;
            }
            index++;
        }
    }
    return true;
}

Интересный поворот состоит в том, что они переходят к байтовому циклу сравнения, только если хэши двух двоичных объектов совпадают. Это, однако, происходит за счет вычисления хэша в конструкторе двоичных объектов (путем обхода массива с для цикла :-)).

24
ответ дан 22 November 2019 в 22:33
поделиться

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

Другой способ оптимизации, аналогичный подходу, показанному выше, - это хранить как можно больше ваших данных в длинном [], а не в байтовом [] с самого начала, например, если вы читаете их последовательно из двоичного файла, или, если вы используете файл с отображением в память, считывайте данные как длинные [] или одиночные длинные значения. Тогда вашему циклу сравнения потребуется только 1/8 от числа итераций, которые он должен был бы сделать для байта [], содержащего такое же количество данных. Это вопрос того, когда и как часто вам нужно сравнивать, а когда и как часто вам нужно обращаться к данным побайтно, например, чтобы использовать их в вызове API в качестве параметра в методе, который ожидает байт []. В конце концов, вы можете сказать только, действительно ли знаете сценарий использования ...

1
ответ дан 22 November 2019 в 22:33
поделиться

Если вы посмотрите, как .NET выполняет string.Equals, вы увидите, что он использует закрытый метод EqualsHelper, который имеет «небезопасную» реализацию указателя. .NET Reflector - ваш друг, чтобы увидеть, как все делается внутри.

Его можно использовать в качестве шаблона для сравнения байтовых массивов, реализацию которого я реализовал в сообщении в блоге Быстрое сравнение байтовых массивов в C # . Я также провел несколько элементарных тестов, чтобы увидеть, когда безопасная реализация быстрее небезопасной.

Тем не менее, если вам действительно не нужна убийственная производительность, я бы пошел на простое сравнение цикла fr.

5
ответ дан 22 November 2019 в 22:33
поделиться

Для сравнения коротких байтовых массивов следующий интересный прием:

if(myByteArray1.Length != myByteArray2.Length) return false;
if(myByteArray1.Length == 8)
   return BitConverter.ToInt64(myByteArray1, 0) == BitConverter.ToInt64(myByteArray2, 0); 
else if(myByteArray.Length == 4)
   return BitConverter.ToInt32(myByteArray2, 0) == BitConverter.ToInt32(myByteArray2, 0); 

Тогда я бы, вероятно, выпал на решение, указанное в вопросе.

Было бы интересно сделать анализ производительности этого кода.

2
ответ дан 22 November 2019 в 22:33
поделиться

P / Invoke Powers activate!

[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;
}
231
ответ дан 22 November 2019 в 22:33
поделиться
Другие вопросы по тегам:

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