如何重写结构's Equals方法提高了C#中的性能



我正在Nutshell中阅读C#,遇到了以下段落:

结构的默认结构相等性比较算法相对较慢。通过重写Equals来接管此过程可以将性能提高五倍。重载==运算符并实现IEquatable<T>可以进行开箱的相等比较,这可以再次将速度提高五倍。

我理解定义==&!=运算符可以通过防止不必要的装箱来提高性能,但我不明白为什么重写Equals可以将性能提高5倍。有人能向我描述一下吗?

提前感谢!

默认的Equals实现也使用装箱(和反射(:

public override bool Equals([NotNullWhen(true)] object? obj)
{
    if (null == obj)
    {
        return false;
    }
    Type thisType = this.GetType(); // <------------ Reflection
    Type thatType = obj.GetType();
    if (thatType != thisType)
    {
        return false;
    }
    object thisObj = (object)this;
    object? thisResult, thatResult; // <------------ Boxing
    // if there are no GC references in this object we can avoid reflection
    // and do a fast memcmp
    if (CanCompareBits(this))
        return FastEqualsCheck(thisObj, obj);
    FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
    for (int i = 0; i < thisFields.Length; i++)
    {
        thisResult = thisFields[i].GetValue(thisObj);
        thatResult = thisFields[i].GetValue(obj);
        if (thisResult == null)
        {
            if (thatResult != null)
                return false;
        }
        else
        if (!thisResult.Equals(thatResult))
        {
            return false;
        }
    }
    return true;
}

还值得一提的是,GetHashCode实现只对第一个非null字段进行散列,因此根据具体情况,您可能会因散列冲突而遇到性能问题。只需覆盖两者。

最新更新