Подтвердить что ты не робот

LINQ Count() пока, это более эффективно?

Скажем, я хочу проверить, есть ли в коллекции по крайней мере 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;
    }
4b9b3361

Ответ 1

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

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

Ответ 2

        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