Data una vasta collezione di oggetti, c'è una differenza di prestazioni tra i seguenti?
Collezione . Contiene :
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Data una vasta collezione di oggetti, c'è una differenza di prestazioni tra i seguenti?
Collezione . Contiene :
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Risposte:
Contains()
è un metodo di istanza e le sue prestazioni dipendono in gran parte dalla raccolta stessa. Ad esempio, Contains()
su a List
è O (n), mentre Contains()
su a HashSet
è O (1).
Any()
è un metodo di estensione e passerà semplicemente attraverso la raccolta, applicando il delegato a ogni oggetto. Ha quindi una complessità di O (n).
Any()
è tuttavia più flessibile poiché è possibile passare un delegato. Contains()
può accettare solo un oggetto.
Contains
è anche un metodo di estensione contro IEnumerable<T>
(sebbene alcune raccolte abbiano anche il proprio Contains
metodo di istanza). Come dici tu, Any
è più flessibile rispetto al Contains
fatto che puoi passargli un predicato personalizzato, ma Contains
potrebbe essere leggermente più veloce perché non è necessario eseguire una chiamata di delegato per ogni elemento.
All()
funziona in modo simile.
Dipende dalla collezione. Se hai una raccolta ordinata, Contains
potresti fare una ricerca intelligente (binario, hash, b-tree, ecc.), Mentre con `Any () sei fondamentalmente bloccato con l'enumerazione finché non la trovi (assumendo LINQ-to-Objects) .
Nota anche che nel tuo esempio, Any()
sta usando l' ==
operatore che verificherà l'uguaglianza referenziale, mentre Contains
userà IEquatable<T>
o il Equals()
metodo, che potrebbe essere sovrascritto.
Suppongo che dipenda dal tipo di myCollection
è che determina come Contains()
viene implementato. Se un albero binario ordinato, ad esempio, potrebbe cercare in modo più intelligente. Inoltre potrebbe prendere in considerazione l'hash dell'elemento. Any()
d'altra parte enumererà attraverso la raccolta fino a trovare il primo elemento che soddisfa la condizione. Non ci sono ottimizzazioni per se l'oggetto avesse un metodo di ricerca più intelligente.
Contains () è anche un metodo di estensione che può funzionare velocemente se lo si utilizza nel modo corretto. Ad esempio:
var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();
Questo darà la query
SELECT Id
FROM Projects
INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item
mentre Any () d'altra parte itera sempre attraverso O (n).
Spero che funzioni ...