简体   繁体   English

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

[英]Performance of == vs Equals in generic C# class

For some reason C# does not allow == operator use in generic classes like here: 出于某种原因,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 ...
            }
        }
    }
}

If I replace == with val.Equals(value) I have code that works as expected but if I look at bytecode it looks much more complicated. 如果我用val.Equals(value)替换==我有代码按预期工作但如果我看字节码它看起来要复杂得多。 A very simple test comparing int variables in the loop using == and Equals() showed that Equals() version was two times slower than "==" version. 使用==和Equals()比较循环中的int变量的一个非常简单的测试表明,Equals()版本比“==”版本慢两倍。

I wonder if there is a way to compare primitive value types in generic classes that would be as fast as == operator. 我想知道是否有一种方法来比较泛型类中的原始值类型,这些类型与==运算符一样快。 Any ideas welcome. 欢迎任何想法。

Edit: I got lost between timers. 编辑:我在计时器之间迷路了。 Performance difference is not as dramatic. 性能差异并不那么显着。 Here are my latest results: 这是我最新的结果:

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

In short: Equals() is good enough. 简而言之:Equals()足够好了。

If you are allowed to add the IEquatable<T> constraint to the class, then you can use the IEquatable<T>.Equals(T other) method declared in that interface: 如果允许将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 ...
            }
        }
    }
}

The reason being that == defaults to reference equality and that makes no sense for value types, the answer will always be false . 原因是==默认引用相等而且对值类型没有意义,答案总是false Because there is no language mechanism to constrain generic types based upon static methods, the compiler simply disallows this as it can't verify that T really has an overloaded == operator. 因为没有语言机制来基于静态方法来约束泛型类型,所以编译器完全不允许这样做,因为它无法验证T是否真的有一个重载的==运算符。

On the other hand if you constraint T to class it will compile just fine because reference equality does make sense for reference types. 另一方面,如果你将T约束到class ,它将编译得很好,因为引用相等确实对引用类型有意义。

The solution is of course IEquatable<T> ; 解决方案当然是IEquatable<T> ; in any sanely implemented struct IEquatable<T>.Equals(T t) will give you value equality semantics and == should behave consistently. 在任何IEquatable<T>.Equals(T t)实现的结构中IEquatable<T>.Equals(T t)将为您提供值相等语义,并且==应该表现一致。

And answering your question, no there is not. 并回答你的问题,不,没有。 If you really need the speed of int == int you will need to implement a non generic specialized class. 如果你真的需要int == int的速度,你需要实现一个非通用的专用类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM