LINQ Count () до, это более эффективно? - PullRequest
11 голосов
/ 09 марта 2012

Скажем, я хочу проверить, есть ли в коллекции хотя бы N элементов.

Это лучше, чем делать?

Count() >= N

Использование:

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

Или даже

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

Как я могу это сравнить?

    /// <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;
    }

Ответы [ 2 ]

5 голосов
/ 09 марта 2012

Есть несколько хорошо документированных оптимизаций, встроенных в метод .Count().В частности, если ваше перечислимое значение ICollection, .Count() будет операцией постоянного времени, так как будет использовать свойство ICollection '.Count

Тем не менее, в общем случае он будет повторять все IEnumerable, чтобы получить счет.Если у вас нет ICollection, вам будет лучше использовать любой из двух предложенных вами способов, если их больше, чем N элементов.Для относительной эффективности этих двух вам придется профилировать их, как предложили другие.

2 голосов
/ 09 марта 2012
        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);

Результаты, в которых PrintTime () распечатывает отметки таймера:

True 20818
True 8774
True 8688
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...