в System.Linq
пространстве имен мы можем теперь расширить наши IEnumerable, чтобы иметь методы расширения Any () и Count () .
Недавно мне сказали, что если я хочу проверить, что коллекция содержит 1 или более элементов внутри, я должен использовать .Any()
метод расширения вместо .Count() > 0
метода расширения, потому что .Count()
метод расширения должен перебирать все элементы.
Во-вторых, некоторые коллекции имеют свойство (не метод расширения), которое является Count
или Length
. Было бы лучше использовать их, а не .Any()
или .Count()
?
да / нет?
.net
linq
performance
.net-3.5
extension-methods
Pure.Krome
источник
источник
Ответы:
Если вы начинаете с чем - то , что имеет
.Length
или.Count
(напримерICollection<T>
,IList<T>
,List<T>
и т.д.) - то это будет самым быстрым вариантом, поскольку он не должен пройти черезGetEnumerator()
/MoveNext()
/Dispose()
последовательность , требуемуюAny()
для проверки непустойIEnumerable<T>
последовательности ,Ибо просто
IEnumerable<T>
тогдаAny()
, как правило, будет быстрее, так как нужно только взглянуть на одну итерацию. Тем не менее, обратите внимание, что реализация LINQ-to-ObjectsCount()
проверяетICollection<T>
(использует.Count
в качестве оптимизации) - поэтому, если ваш базовый источник данных является непосредственно списком / коллекцией, не будет большой разницы. Не спрашивайте меня, почему он не использует неуниверсальныйICollection
...Конечно, если вы использовали LINQ для фильтрации и т. Д. (И
Where
т. Д.), У вас будет последовательность, основанная на блоках итераторов, и этаICollection<T>
оптимизация бесполезна.В общем с
IEnumerable<T>
: придерживатьсяAny()
;-pисточник
(somecollection.Count > 0)
? Был ли труден для понимания весь наш код до введения метода LINQ .Any ()?someCollection.Count > 0
это так же ясно, какsomeCollection.Any()
и имеет дополнительное преимущество большей производительности и не требует LINQ. Конечно, это очень простой случай, и другие конструкции, использующие операторы LINQ, передадут намерения разработчиков намного яснее, чем эквивалентная опция без LINQ.Примечание: я написал этот ответ, когда Entity Framework 4 был актуален. Смысл этого ответа не состоял в том, чтобы войти в тривиальное по
.Any()
сравнению с.Count()
тестированием производительности. Смысл в том, чтобы сигнализировать, что EF далека от совершенства. Новые версии лучше ... но если у вас есть часть кода, которая работает медленно и использует EF, протестируйте с прямым TSQL и сравните производительность, а не полагайтесь на предположения (что.Any()
ВСЕГДА быстрее, чем.Count() > 0
).Хотя я согласен с большинством ответов и комментариев, за которые проголосовали, особенно если речь идет о намерениях разработчиков точных
Any
сигналов лучше, чем у меня, я столкнулся с ситуацией, когда на SQL Server счетчик работает на порядок быстрее (EntityFramework 4).Count() > 0
Вот запрос с
Any
этим исключением тайм-аута (на ~ 200.000 записей):Count
Версия выполняется за считанные миллисекунды:Мне нужно найти способ посмотреть, какой именно SQL выдают оба LINQ - но очевидно, что существует огромная разница в производительности между
Count
иAny
в некоторых случаях, и, к сожалению, кажется, что вы не можете просто придерживатьсяAny
во всех случаях.РЕДАКТИРОВАТЬ: Здесь генерируются SQL. Красавицы как видите;)
ANY
:COUNT
:Кажется, что чисто Where с EXISTS работает намного хуже, чем вычисление Count и затем выполнение Where с Count == 0.
Дайте мне знать, если вы, ребята, увидите какую-то ошибку в моих выводах. Что можно извлечь из всего этого, независимо от обсуждения Any vs Count, так это то, что любой более сложный LINQ намного лучше, если его переписать как хранимую процедуру;).
источник
Поскольку это довольно популярная тема, и ответы на нее разные, мне пришлось по-новому взглянуть на проблему.
Тестирование env: EF 6.1.3, SQL Server, 300 тыс. Записей
Настольная модель :
Тестовый код:
Результаты:
Любой () ~ 3 мс
Count () ~ 230мс для первого запроса, ~ 400мс для второго
Примечания:
В моем случае EF не генерировал SQL, как @Ben, упомянутый в его посте.
источник
Count() > 0
. : DРЕДАКТИРОВАТЬ: это было исправлено в версии EF 6.1.1. и этот ответ больше не актуален
Для SQL Server и EF4-6 Count () работает примерно в два раза быстрее, чем Any ().
Когда вы запускаете Table.Any (), он генерирует что-то вроде ( предупреждение: не повредите мозг, пытаясь это понять )
это требует 2 сканирования строк с вашим состоянием.
Я не люблю писать,
Count() > 0
потому что это скрывает мое намерение. Я предпочитаю использовать пользовательский предикат для этого:источник
Это зависит от того, насколько велик набор данных и каковы ваши требования к производительности?
Если нет ничего гигантского, используйте наиболее читаемую форму, которая для меня является любой, потому что она короче и удобочитаема, а не уравнение.
источник
Что касается метода Count () , если IEnumarable является ICollection , то мы не можем выполнить итерацию по всем элементам, потому что мы можем извлечь поле Count из ICollection , если IEnumerable не является ICollection, мы должны выполнить итерацию по всем элементам, используя некоторое время с a MoveNext , посмотрите .NET Framework Code:
Ссылка: Ссылочный источник Enumerable
источник
Вы можете сделать простой тест, чтобы понять это:
Проверьте значения testCount и testAny.
источник
Count
заменить методом Count () vs .Any (), а не свойством. Вам нужно время итераций.Если вы используете Entity Framework и у вас огромная таблица с множеством записей, Any () будет намного быстрее. Я помню, как однажды я хотел проверить, была ли таблица пустой и в ней миллионы строк. Для завершения Count ()> 0 потребовалось 20-30 секунд. Это было мгновенно с Any () .
Any () может повысить производительность, потому что может не потребоваться повторять коллекцию, чтобы получить количество вещей. Это просто должно ударить одного из них. Или, скажем, для LINQ-to-Entities, сгенерированный SQL будет IF EXISTS (...), а не SELECT COUNT ... или даже SELECT * ....
источник