I want to compare a large Struct in C# via Equals, which in turn is implemented through IEquatable<T> Interface.
My Problem is that it performs very poorly, as my struct is rather large. Imagine a simplified version of the struct like the follwoing:

public struct Data
{
    public byte b0;
    public byte b1;
    public byte b2;
    public byte b3;
    public byte b4;
    public byte b5;
    public byte b6;
    public byte b7;
}

我现在写一个简单的Equals:

public bool Equals(Data other)
{
    return b0 == other.b0 &&
           b1 == other.b1 &&
           ... 
}

有什么方法可以使equals方法更高效吗?

Update

根据给出的here的定义,我的 struct 类型是unmanaged.

推荐答案

事实上,有一种方法可以提高复杂 struct 的性能.

以你的例子为例:

public struct Data
{
    public byte b0;
    public byte b1;
    public byte b2;
    public byte b3;
    public byte b4;
    public byte b5;
    public byte b6;
    public byte b7;
}

然后,您可以编写equals方法,如下所示:

public bool Equals(Data other)
{ 
    DatHelper helperThis = Unsafe.As<Data, DatHelper>(ref this); 
    DatHelper helperOther = Unsafe.As<Data, DatHelper>(ref other); 
    return helperThis.Equals(helperOther); 
}

DataHelper看起来有点像这样:

public struct DataHelper
{
    public long l0;
    
    public bool Equals(DataHelper other)
    {
        return l0 == other.l0; 
    }
}

为什么这会奏效?

这里重要的是,这两个 struct 在内存中具有相同的大小.然后我们可以使用Unsafe.AsData的内存重新解释为DataHelper,这允许我们比较,在我们的例子中,一长与一长,而不是八个字节与八个字节.

这是可扩展的. 例如,如果您有一个大小为33个字节的 struct ,那么您可以将DataHelper创建为4个长和1个字节,并对它们进行比较.

唯一必须保证的是:

  1. 你必须使用一个 struct 体.这对类不起作用,因为类只包含它们数据的位置,而 struct 体包含它们的实际数据.
  2. 两个 struct 的大小必须相同.

像往常一样,衡量您是否真的看到了性能提升.

Csharp相关问答推荐

我可以将Expressc操作设置为在另一个Expressc操作完成后自动发生吗?

自定义JsonEditor,用于将SON序列化为抽象类

使用LINQ to XML获取元素值列表是不起作用的

通过条件列表删除/更新EF Core 7中的实体的有效方法

如何在C#中使用正则表达式抓取用逗号分隔的两个单词?

返回TyedResults.BadRequest<;字符串>;时问题详细信息不起作用

C#-从基类更新子类

MigraDoc文档

为什么Regex.IsMatch(";\\t";,";\\t";)返回FALSE而不是TRUE?

在C#中,将两个哈希集连接在一起的时间复杂度是多少?

System.Text.Json .NET 8多形态语法化

正在寻找新的.NET8 Blazor Web应用程序.如何将.js添加到.razor页面?

升级后发出SWITCH语句

在PostgreSQL上使用ExecuteSqlRawAsync的C#11原始字符串文字有区分大小写的问题

在C#.NET项目中启动时,如何等待提升的PowerShell进程退出?

正在从最小API-InvocationConext.Arguments中检索参数的FromBodyAttribute

WPF动态设置弹出窗口水平偏移

当`JToken?`为空时?

如何读取TagHelper属性的文本值?

仅在Blazor Web App中覆盖生产的基本路径(.NET8中的_Hosts.cshtml文件功能?)