简体   繁体   中英

LINQ Count() until, is this more efficient?

Say I want to check whether there are at least N elements in a collection.

Is this better than doing?

Count() >= N

Using:

    public static bool AtLeast<T>(this IEnumerable<T> enumerable, int max)
    {
        int count = 0;
        return enumerable.Any(item => ++count >= max);
    }

Or even

    public static bool Equals<T>(this IEnumerable<T> enumerable, int amount)
    {
        return enumerable.Take(amount).Count() == amount;
    }

How could I benchmark this?

    /// <summary>
    /// Returns whether the enumerable has at least the provided amount of elements.
    /// </summary>
    public static bool HasAtLeast<T>(this IEnumerable<T> enumerable, int amount)
    {
        return enumerable.Take(amount).Count() == amount;
    }

    /// <summary>
    /// Returns whether the enumerable has at most the provided amount of elements.
    /// </summary>
    public static bool HasAtMost<T>(this IEnumerable<T> enumerable, int amount)
    {
        return enumerable.Take(amount + 1).Count() <= amount;
    }

There are some well-documented optimizations built in to the .Count() method. Specifically, if your enumerable is an ICollection , .Count() will be a constant-time operation as it will use the ICollection 's .Count property.

However, in the general case it will iterate the entire IEnumerable to get the count. If you do not have an ICollection , you'd be better off using either of your two suggested methods when there are more than N elements. For the relative performance of those two, you'd have to profile them as others have suggested.

        var list = Enumerable.Range(1, 1000000);
        var t = new Stopwatch();

        t.Restart();
        var count = list.Count() > 100000;
        t.Stop();
        PrintTime(t, count);

        t.Restart();
        var atLeast = list.AtLeast(100000);
        t.Stop();
        PrintTime(t, atLeast);

        t.Restart();
        var equals = list.Equalss(100000);
        t.Stop();
        PrintTime(t, equals);

Results where PrintTime() prints out the timer ticks:

True 20818
True 8774
True 8688

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