Sirwan Afifi
Sirwan Afifi

Reputation: 10824

Most efficient way to compare two List<T>

I'm trying to compare two lists. Here's the extension method I'm trying to use:

public static bool EqualsAll<T>(this IList<T> a, IList<T> b)
{
    if (a == null || b == null)
        return (a == null && b == null);

    if (a.Count != b.Count)
        return false;

    EqualityComparer<T> comparer = EqualityComparer<T>.Default;

    for (int i = 0; i < a.Count; i++)
    {
        if (!comparer.Equals(a[i], b[i]))
            return false;
    }

    return true;
}

I've already asked this question here. But I need more information about that. the answerer said that It's better to use SequenceEqual instead of for loop.

Now my question is that which one of two approaches is the most efficient way for comparing two List<T>?

Upvotes: 2

Views: 905

Answers (3)

usr
usr

Reputation: 171178

The most efficient way to compare to List<T> objects is to not go through interface dispatch by using IList. Instead, specialize the type to List<T>. The arguments should be List<T>.

This saves a lot of indirect calls. It's clearly faster than the IEnumerable based SequenceEquals while requires two indirect calls per element.

Also, you need to cache the count.

It would be best if List<T> had a built-in method, or implemented a certain interface or allowed access to its internal buffer. But none of that is available.

I guess the fastest possible way is to runtime-compile a function that returns you the internal buffers of each of those lists. Then, you can compare arrays which is much faster. Clearly, this relies on Full Trust and undocumented internals... Proceed with care.

There are also things you can do to avoid the cost of the comparer. It really depends on how important this issue is. You can go to great length to optimize this.

Upvotes: 3

Codor
Codor

Reputation: 17605

As IList<T> implements IEnumerable<T>, as documented here, I would believe that

a.SequenceEqual(b)

is a reasonable way to do the comparison, with the exentsion method being documented here.

Upvotes: 3

Dave Zych
Dave Zych

Reputation: 21887

I'm sure they're both relatively equal in performance since both are doing a sequence equal check. SequenceEqual doesn't do any magic - it still loops.

As for which one to use, go with SequenceEqual - it's built into the framework, other programmers already know it's functionality, and most importantly, there's no need to reinvent the wheel.

Upvotes: 6

Related Questions