Exploring the .NET CoreFX Part 6: Use IEquatable for Higher-Performance Equals()

This is part 6 of my Exploring the .NET CoreFX Series.

Let’s say you are writing a custom IList which contains the following code:

public class MyList<T> : IList<T>
{
    private T[] array;

    ...

    public int IndexOf(T item)
    {
        for (int i = 0; i != array.Length; ++i) {
            if (this.array[i].Equals(item)) {
                return i;
            }
        }

        return -1;
    }
}

The above code uses T‘s implementation of Object.Equals(), which is defined as:

public virtual bool Equals(Object obj);

If T is a value type, it will be automatically boxed by the compiler, which has a slight performance cost. However, if you knew that T implemented IEquatable, then you could avoid the boxing entirely. For example, this code would be slightly better performing than the above for value types:

public class MyList<T> : IList<T> where T : IEquatable<T>
{
    // Everything else is the same as above
}

However, it is inadvisable to require MyList to only contain objects which implement IEquatable.

You can get the best of both worlds by using EqualityComparer.Default to choose IEquatable.Equals() when available, and Object.Equals() otherwise, as follows:

public class MyList<T> : IList<T>
{
    private T[] array;

    ...

    public int IndexOf(T item)
    {
        return IndexOf(item, EqualityComparer<T>.Default);
    }

    public int IndexOf(T item, IEqualityComparer<T> equalityComparer)
    {
        for (int i = 0; i != array.Length; ++i) {
            if (equalityComparer.Equals(this.array[i], item)) {
                return i;
            }
        }

        return -1;
    }
}

Recommendations

  1. Implement IEquatable on value types for which you expect .Equals() to be called a lot, especially those you put into arrays, lists, or hash tables.

About Steven Engelhardt, CFA, AIF
Adjunct Professor of Software Engineering at DePaul University • Software Engineering, Data & Analytics in FinTech • Lives in Chicago, IL

One Response to Exploring the .NET CoreFX Part 6: Use IEquatable for Higher-Performance Equals()

  1. Pingback: Exploring the .NET Core Part 7: Reference Versus Structural Equality | Steven Engelhardt

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s