通用C#类中== vs Equals的性能

时间:2016-12-29 23:19:51

标签: c# performance generics operators

由于某些原因,C#不允许在这样的泛型类中使用==运算符:

class Mine<T> where T : struct
{
    T val;
    public T Value 
    { 
        set 
        { 
            if (val == value) // Operator '==' cannot be applied to operands of type T and T happens here
            {
                // .. do something ...
            }
        }
    }
}

如果我用val.Equals(value)替换==我的代码可以按预期工作,但如果我查看字节码,它看起来要复杂得多。 使用==和Equals()比较循环中的int变量的一个非常简单的测试表明,Equals()版本比&#34; ==&#34;慢两倍。版。

我想知道是否有一种方法可以比较泛型类中的原始值类型,这种类型与==运算符一样快。 欢迎任何想法。

修改 我在定时器之间迷路了。性能差异并不那么显着。以下是我的最新结果:

== operator                            1974380 ticks
Equals()                               1976358 ticks
== operator in another static function 1974604 ticks
EqualityComparer<int>.Default...      32486695 ticks

简而言之:Equals()足够好了。

2 个答案:

答案 0 :(得分:5)

如果允许将IEquatable<T>约束添加到类中,则可以使用该接口中声明的IEquatable<T>.Equals(T other)方法:

class Mine<T> where T : struct, IEquatable<T>
{
    T val;
    public T Value
    {
        set
        {
            if (val.Equals(value)) // 
            {
                // .. do something ...
            }
        }
    }
}

答案 1 :(得分:4)

原因是==默认引用相等并且对值类型没有意义,答案将始终为false。因为没有语言机制来基于静态方法来约束泛型类型,所以编译器完全不允许这样做,因为它无法验证T是否真的有一个重载==运算符。

另一方面,如果您将T约束为class,它将编译得很好,因为引用相等确实对引用类型有意义。

解决方案当然是IEquatable<T>;在任何明智地实现的struct IEquatable<T>.Equals(T t)中都会给你值相等的语义,而==应该表现得一致。

回答你的问题,不,没有。如果你真的需要int == int的速度,你需要实现一个非通用的专业类。