C#字节数组比较

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

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

例如,字节数组{0x1, 0x2}{0x1, 0x2} 。 但字节数组{0x1, 0x2}和字节数组{0x2, 0x1}不相同。

好吧,你可以使用:

 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不能(或不执行) - 例如前期长度检查。 直接arrays访问也比使用枚举器更有效。

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

你可以通过一次比较32位或64位而不是8位来使非托管代码中的速度更快 - 但我不想在运行时编写代码。

您可以使用SequenceEqual方法:

 bool areEqual = firstArray.SequenceEqual(secondArray); 

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

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

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

如果你想要它真的很快,你可以使用不安全的代码(这并不总是可行):

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

如果您不太关心性能,可以考虑IStructuralEquatable

.NET Framework受以下版本支持:4.5,4

结构相等意味着两个对象是相等的,因为它们具有相等的值。 它与参考平等不同。

例:

 static bool ByteArrayCompare(byte[] a1, byte[] a2) { IStructuralEquatable eqa1 = a1; return eqa1.Equals(a2, StructuralComparisons.StructuralEqualityComparer); } 

参考

  1. IStructuralEquatable和IStructuralComparable解决了什么问题?
  2. 为什么IStructuralEquatable和IStructuralComparable不通用?
  3. IStructuralEquatable接口