Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 948
Optional Option Avatar asked Dec 29 '16 23:12

Optional Option


1 Answers

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.

like image 52
InBetween Avatar answered Sep 29 '22 00:09

InBetween