简体   繁体   中英

Performance of == vs Equals in generic C# class

For some reason C# does not allow == operator use in generic classes like here:

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. A very simple test comparing int variables in the loop using == and Equals() showed that Equals() version was two times slower than "==" version.

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.

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:

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 . 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.

On the other hand if you constraint T to class it will compile just fine because reference equality does make sense for reference types.

The solution is of course IEquatable<T> ; in any sanely implemented struct IEquatable<T>.Equals(T t) will give you value equality semantics and == should behave consistently.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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