Используя LINQ для коллекций, в чем разница между следующими строками кода?
if(!coll.Any(i => i.Value))
а также
if(!coll.Exists(i => i.Value))
Обновление 1
Когда я разбираю, .Exists
похоже, что нет кода.
Обновление 2
Кто-нибудь знает, почему там нет кода для этого?
c#
linq
collections
Энтони Д
источник
источник
Ответы:
Смотрите документацию
List.Exists (Метод объекта - MSDN)
Это существует с .NET 2.0, так до LINQ. Предназначено для использования с делегатом Predicate , но лямбда-выражения обратно совместимы. Кроме того, только у Списка есть это (даже IList)
IEnumerable.Any (метод расширения - MSDN)
Это новое в .NET 3.5 и использует Func (TSource, bool) в качестве аргумента, так что это было предназначено для использования с лямбда-выражениями и LINQ.
По поведению они идентичны.
источник
List<>
методов экземпляра .NET 2 .Разница в том, что Any - это метод расширения для любого,
IEnumerable<T>
определенного в System.Linq.Enumerable. Это может быть использовано в любомIEnumerable<T>
случае.Exists не является методом расширения. Я думаю, что колл имеет тип
List<T>
. Если так, то Exists - это метод экземпляра, который очень похож на Any.Короче говоря , методы по сути одинаковы. Один более общий, чем другой.
источник
TLDR; По производительности,
Any
кажется, медленнее (если я настроил это правильно, чтобы оценить оба значения практически одновременно)генератор тестового списка:
С 10М записями
С 5М записей
С 1М записей
С 500k, (я также переключил порядок, в котором они оцениваются, чтобы увидеть, нет ли дополнительной операции, связанной с тем, что запускается первым).
С 100к записей
Казалось бы,
Any
медленнее по величине 2.Редактировать: для записей 5 и 10M я изменил способ создания списка и
Exists
неожиданно стал медленнее, чем то,Any
что подразумевает, что что-то не так в моем тестировании.Новый механизм тестирования:
Edit2: Хорошо, поэтому, чтобы исключить какое-либо влияние на генерацию тестовых данных, я записал все это в файл и теперь прочитал его оттуда.
10M
5M
1M
500k
источник
Как продолжение ответа Матаса на бенчмаркинг.
TL / DR : Exists () и Any () одинаково быстрые.
Прежде всего: бенчмаркинг с использованием секундомера не является точным ( см. Ответ series0ne на другую, но похожую тему ), но он гораздо точнее, чем DateTime.
Способ получить действительно точные показания с помощью профилирования производительности. Но один из способов получить представление о том, как производительность двух методов соотносится друг с другом, состоит в том, чтобы выполнить оба метода много раз, а затем сравнить самое быстрое время выполнения каждого из них. Таким образом, на самом деле не имеет значения, что JITing и другие шумы дают нам плохие показания (и это делает ), потому что оба исполнения « одинаково вводят в заблуждение » в некотором смысле.
После выполнения вышеуказанного кода 4 раза (что, в свою очередь, составляет 1 000
Exists()
иAny()
для списка с 1 000 000 элементов), нетрудно увидеть, что методы в значительной степени одинаково быстры.Там является небольшая разница, но это слишком маленькая разница не может быть объяснена фоновым шумом. Я полагаю, что если сделать 10 000 или 100 000
Exists()
иAny()
вместо этого, эта небольшая разница исчезнет более или менее.источник
Кроме того, это будет работать, только если значение имеет тип bool. Обычно это используется с предикатами. Любой предикат, как правило, используется для определения того, существует ли какой-либо элемент, удовлетворяющий заданному условию. Здесь вы просто делаете карту из вашего элемента i в свойство bool. Он будет искать «я», свойство Value которого имеет значение true. После этого метод вернет true.
источник
Когда вы исправите измерения - как упомянуто выше: Любое и Существует, и добавив среднее - мы получим следующий результат:
источник