Есть ли более быстрый способ, чем .Any (), чтобы найти, если IEnumerable <T>имеет какие-либо данные? - PullRequest
4 голосов
/ 22 мая 2019

Когда я запускаю профилировщик для моего кода, я показываю общее время выполнения 20 секунд, 14 секунд из которых (14 788,4 мс) занято вызовом IEnumerable.Any () есть какой-нибудь способ ускорить этовообще?

В таблице, из которой выполняется извлечение, в общей сложности ~ 484 000 записей, поэтому лучше всего избегать помещения в память.

Я пытался заменить IEnumerable.Any () на IEnumerable..Count ()> 0 и использование IEnumerable.GetEnumerator (). MoveNext ()

Все это не дает существенных изменений во времени выполнения.

IEnumerable<Registration> result = [Fill by Query] (19ms)
[Conditions] (<0.1ms for all)
[Tried all of the following with no performance impact]
return result != null && result.Any(); (14000ms)
return result != null && result.Count() > 0; (14000ms)
return result != null && result.GetEnumerator().MoveNext(); (14000ms)
return (result?.Any() ?? false); (14000ms)

Я надеюсь, что смогунайдите что-то, что уменьшит общее время выполнения до разумного числа, единственное узкое место - IEnumerable.Any ().

1 Ответ

10 голосов
/ 22 мая 2019

Вам необходимо вызвать Queryable.Any, а не Enumerable.Any, чтобы фактический запрос к базе данных можно было настроить так, чтобы он только запрашивал, существуют ли какие-либо элементы. Превратив IQueryable в IEnumerable, вы гарантируете, что все выполняемые над ним операции включают материализацию результатов запроса в памяти до того, как эта операция может быть выполнена.

...