我怎么能这么快?

我当然能做到:

static bool ByteArrayCompare(byte[] a1, byte[] a2)
{
    if (a1.Length != a2.Length)
        return false;

    for (int i=0; i<a1.Length; i++)
        if (a1[i]!=a2[i])
            return false;

    return true;
}

但我正在寻找一个BCL函数或某种高度优化的成熟方法来实现这一点.

java.util.Arrays.equals((sbyte[])(Array)a1, (sbyte[])(Array)a2);

很好地工作,但它看起来不适合x64.

请注意我的超快答案here.

推荐答案

用户gil建议生成此解决方案的不安全代码:

// Copyright (c) 2008-2013 Hafthor Stefansson
// Distributed under the MIT/X11 software license
// Ref: http://www.opensource.org/licenses/mit-license.php.
static unsafe bool UnsafeCompare(byte[] a1, byte[] a2) {
  if(a1==a2) return true;
  if(a1==null || a2==null || a1.Length!=a2.Length)
    return false;
  fixed (byte* p1=a1, p2=a2) {
    byte* x1=p1, x2=p2;
    int l = a1.Length;
    for (int i=0; i < l/8; i++, x1+=8, x2+=8)
      if (*((long*)x1) != *((long*)x2)) return false;
    if ((l & 4)!=0) { if (*((int*)x1)!=*((int*)x2)) return false; x1+=4; x2+=4; }
    if ((l & 2)!=0) { if (*((short*)x1)!=*((short*)x2)) return false; x1+=2; x2+=2; }
    if ((l & 1)!=0) if (*((byte*)x1) != *((byte*)x2)) return false;
    return true;
  }
}

它对尽可能多的数组进行基于64位的比较.这取决于数组开始对齐qword这一事实.如果没有qword对齐,它就可以工作,只是速度不如qword对齐.

它比简单的for循环快7个定时器.使用J#library与原来的for循环相当.使用.SequenceEqual的运行速度大约慢七倍;我觉得只是因为它使用了IEnumerator.下一步.我认为基于LINQ的解决方案至少有那么慢或更糟.

.net相关问答推荐

从Couchbase删除_txn文档的推荐方法?""

";Make Async ValueTask/ValueTask方法分期分配发生了什么?

Docker镜像mcr.microsoft.com/dotnet/aspnet:8.0不能在Windows上构建

Blazor服务器应用程序需要在页面上点击才能与元素交互

EGC / 文本元素上的 .NET String.Split

C#/.NET + VisualStudio,命名空间问题

为什么这个多态 C# 代码会打印它的功能?

如何使用 C# 中的代码更改网络设置(IP 地址、DNS、WINS、主机名)

为什么 LINQ .Where(predicate).First() 比 .First(predicate) 快?

如何在不丢失数据的情况下重命名 Entity Framework 5 Code First 迁移中的数据库列?

C# 属性实际上是方法吗?

如何在我的 C# 程序的面板中运行另一个应用程序?

我可以在没有两个查询的情况下通过布尔标准将 IEnumerable 一分为二吗?

C#As的 VB.NET 类似功能

如何找到二维数组的大小?

如何从其十六进制 RGB 字符串创建 System.Drawing.Color?

IronPython 与 Python .NET

如果选中,则更改列表框项的 WPF DataTemplate

如果锁定的对象内部发生异常,它会保持锁定状态吗?

枚举和匹配属性的 C# 命名约定