我整理了几种比较字节数组的不同方法,我使用了任意长度为 10000 的数组,并假设两个比较的数组长度相同(因为“宽相位”长度检查显然不是很有趣:))
也许您可以以此为基础来决定在比较数组是否相等时使用哪种方法。
结果是三个场景(相等、第一个元素不同和最后一个元素不同)的 5 次迭代的平均值,时间以毫秒为单位。
---------------
Identical elements
---------------
SequenceEqual: 5.98142
BasicEqual: 0.11864
UnsafeMemCmp: 0.15542
SafeMemCmp: 0.12896
---------------
First element different
---------------
SequenceEqual: 0.00056
BasicEqual: 0.00012
UnsafeMemCmp: 0.0002
SafeMemCmp: 0.00182
---------------
Last element different
---------------
SequenceEqual: 0.14942
BasicEqual: 0.03178
UnsafeMemCmp: 0.0015
SafeMemCmp: 0.00326
---------------
我选择的 4 种方法是:
SequentalEqual
static bool SequenceEqual(byte[] arr1, byte[] arr2)
{
return arr1.SequenceEqual(arr2);
}
基本相等
static bool BasicEqual(byte[] arr1, byte[] arr2)
{
for (var i = 0; i < 10000; i++)
if (arr1[i] != arr2[i])
return false;
return true;
}
UnsafeMemCmp
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern unsafe int memcmp(byte* b1, byte* b2, int count);
static unsafe bool UnsafeMemCmp(byte[] arr1, byte[] arr2)
{
fixed (byte* b1 = arr1, b2 = arr2)
{
return memcmp(b1, b2, 10000) == 0;
}
}
SafeMemCmp
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int memcmp(IntPtr b1, IntPtr b2, int count);
static bool SafeMemCmp(byte[] arr1, byte[] arr2)
{
var a = Marshal.AllocHGlobal(arr1.Length);
var b = Marshal.AllocHGlobal(arr2.Length);
try
{
Marshal.Copy(arr1, 0, a, arr1.Length);
Marshal.Copy(arr2, 0, b, arr2.Length);
return memcmp(a, b, 10000) == 0;
}
finally
{
Marshal.FreeHGlobal(a);
Marshal.FreeHGlobal(b);
}
}
为了完成,测试使用以下方法运行:
static void RunTest(string name, Func<byte[], byte[], bool> action, byte[] a, byte[] b)
{
TimeSpan total = TimeSpan.Zero;
for (var i = 0; i < 5; i++)
{
_stopwatch.Reset();
_stopwatch.Start();
action(a, b);
_stopwatch.Stop();
total += _stopwatch.Elapsed;
}
Console.WriteLine(name + ": " + (total.TotalMilliseconds / 5));
}