C#字节数组比较

Geo*_*ge2 14 .net c# bytearray

我使用.NET 3.0在C#中有两个字节数组.

比较两个字节数组是否包含每个元素的相同内容的"最有效"方法是什么?

例如,字节数组{0x1, 0x2}{0x1, 0x2}.但字节数组{0x1, 0x2}和字节数组{0x2, 0x1}不一样.

Jon*_*eet 37

好吧,你可以使用:

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;
}
Run Code Online (Sandbox Code Playgroud)

(我通常会使用大括号来表示所有内容,但我认为我只是为了改变而尝试这种布局样式......)

这有一些SequenceEqual不能(或不执行)的优化- 例如前期长度检查.直接阵列访问也比使用枚举器更有效.

无可否认,在大多数情况下不太可能产生显着差异......

你可以有可能通过使其在一个时间,而不是8比32或64位,使其更快非托管代码-但我不喜欢代码的飞行.

  • @Lijo:我承认我从未完全理解“IStructuralEquatable”以及何时合适。 (2认同)

Luk*_*keH 26

您可以使用以下SequenceEqual方法:

bool areEqual = firstArray.SequenceEqual(secondArray);
Run Code Online (Sandbox Code Playgroud)

正如评论中所提到的,SequenceEqual需要.NET 3.5(或LINQBridge,如果您使用的是VS2008并且针对早期版本的框架).

  • (尝试通过SequenceEqual比较包含1,000,000个条目的字节数组和包含1,000,001个条目的字节数组.在注意到它们具有不同的长度之前,它将直到最后...) (7认同)

Guf*_*ffa 5

Jon提到使用不安全的代码一次比较多个字节,所以我不得不试一试:

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;
}
Run Code Online (Sandbox Code Playgroud)

安全代码得到了相当优化(例如,编译器知道它不必检查索引边界),所以我不希望不安全代码更快.任何显着差异都来自于一次比较几个字节的能力.