Biorąc pod uwagę ogromną kolekcję obiektów, czy istnieje różnica w wydajności między poniższymi?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Biorąc pod uwagę ogromną kolekcję obiektów, czy istnieje różnica w wydajności między poniższymi?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Odpowiedzi:
Contains()
jest metodą instancji, a jej wydajność zależy w dużej mierze od samej kolekcji. Na przykład Contains()
na a List
jest O (n), podczas gdy Contains()
na a HashSet
jest O (1).
Any()
jest metodą rozszerzającą i po prostu przejdzie przez kolekcję, stosując delegata do każdego obiektu. Dlatego ma złożoność O (n).
Any()
jest jednak bardziej elastyczny, ponieważ możesz przekazać delegata. Contains()
może przyjąć tylko przedmiot.
Contains
jest również metodą rozszerzającą przeciwko IEnumerable<T>
(chociaż niektóre kolekcje mają również własne Contains
metody instancji). Jak mówisz, Any
jest bardziej elastyczny niż Contains
dlatego, że możesz przekazać mu niestandardowy predykat, ale Contains
może być nieco szybszy, ponieważ nie musi wykonywać wywołania delegata dla każdego elementu.
All()
działa podobnie.
To zależy od kolekcji. Jeśli masz uporządkowaną kolekcję, Contains
możesz przeprowadzić inteligentne wyszukiwanie (binarne, hash, b-tree itp.), Podczas gdy z `Any () w zasadzie utkniesz z wyliczaniem, dopóki go nie znajdziesz (zakładając LINQ-to-Objects) .
Należy również zauważyć, że w przykładzie, Any()
jest za pomocą ==
operatora, który będzie sprawdzał referencyjnym równości, podczas gdy Contains
użyje IEquatable<T>
lub Equals()
metoda, która może być pominięte.
Przypuszczam, że zależałoby to od typu, myCollection
który dyktuje sposób Contains()
realizacji. Na przykład posortowane drzewo binarne może wyszukiwać mądrzej. Może również uwzględniać hash elementu. Any()
z drugiej strony wyliczy całą kolekcję, aż zostanie znaleziony pierwszy element spełniający warunek. Nie ma optymalizacji, jeśli obiekt miałby inteligentniejszą metodę wyszukiwania.
Contains () jest również metodą rozszerzającą, która może działać szybko, jeśli używasz jej we właściwy sposób. Na przykład:
var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();
To da zapytanie
SELECT Id
FROM Projects
INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item
natomiast Any () z drugiej strony zawsze iteruje przez O (n).
Mam nadzieję, że to zadziała ....