Что более эффективно в .Any и .Count в C # (методы расширения)

public void MethodName(ObservableCollection<DataCollection> dataCollection)
    {
        if (dataCollection != null)
        {
            IsChecked = dataCollection.Any(o => o.DataCollectionID.Equals(30));

            IsChecked = dataCollection.Where(o => o.DataCollectionID.Equals(30)).Count() > 0;
        }            
    }

Может ли кто-нибудь объяснить мне, что может быть наиболее эффективным способом использования двух указанных выше фильтров? .Любой? или .Where.Count?

Примечание. Учтите, что в коллекции dataCollection более 10 000 элементов.

Пожалуйста, посоветуй мне. Спасибо


person Rosh    schedule 19.08.2015    source источник
comment
Мой совет - протестируйте это сами.   -  person Zohar Peled    schedule 19.08.2015
comment
С Any, как только условие выполнено, метод завершается. С Count он должен пройти весь путь до конца. Это действительно то, что вы должны были выяснить после небольшого исследования.   -  person Daniel Kelley    schedule 19.08.2015
comment
over 10,000 items это немного. для меня звучит как микрооптимизация. это вообще твое узкое место? что говорит ваше профилирование? если вы хотите выполнить микрооптимизацию только ради этого, пропустите LINQ полностью. или хотя бы просто PLINQ.   -  person Num Lock    schedule 19.08.2015


Ответы (1)


Обзор фреймворка ... это зависит от обстоятельств. Мои первоначальные инстинкты в гипотетической стране:

Any() проверяет, есть ли единственное значение. Если да, то возвращается истина. Это операция O (1).

Count() должен будет выполнить одно из следующих действий:

1) получить доступ к текущему счету элементов в коллекции или 2) подсчитать элементы в коллекции

В лучшем случае (# 1) операция O (1). В худшем случае (# 2) это O (n).

На самом деле Any() использует итератор коллекции, чтобы определить, есть ли следующее значение. Таким образом, это зависит от коллекции, является ли Any() операцией O (1). Если это плохая реализация, возможно, это будет O (n).

Например, предположим, что итератор Array глуп и ищет первое ненулевое значение. Он должен проверить каждый элемент в массиве, поэтому Any() в этом случае означает O (n). (Фактически, Any() возвращает true для любого массива длиной> 1).

Count() пытается увидеть, реализует ли коллекция ICollection или ICollection<T>, и если да, возвращает значение свойства Count. Если базовая реализация сохраняет текущую вкладку, это может быть O (1). В противном случае это может быть O (n) худший случай.

Если перечисляемый не реализует один из этих интерфейсов, Count() просто выполняет итерацию по всей коллекции, считая по пути. Это О (п).

tl; dr: согласно реализации, Any(), скорее всего, будет намного быстрее, чем Count().

person Community    schedule 19.08.2015
comment
Я считаю, что номер 1 будет O (1) в лучшем случае, но O (n / 2) (так что O (n)) в среднем случае. Число 2 всегда O (n). Очевидно, что номер 1, как правило, более эффективен, но определенно не каждый раз O (1) (постоянное время). - person johnnyRose; 19.08.2015
comment
@johnnyRose В среднем случае? (К вашему сведению, я сейчас проверяю источник) ... Это был бы ужасный дизайн. Вы думаете об одном элементе в конце массива? Да, я это вижу. BRB. - person ; 19.08.2015
comment
O(1) для Any было бы лучшим сценарием. Не всегда. - person Habib; 19.08.2015
comment
@ Хабиб ага. Проверка источника помогает. - person ; 19.08.2015