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 Listjest O (n), podczas gdy Contains()na a HashSetjest 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.
Containsjest również metodą rozszerzającą przeciwko IEnumerable<T>(chociaż niektóre kolekcje mają również własne Containsmetody instancji). Jak mówisz, Anyjest bardziej elastyczny niż Containsdlatego, ż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ę, Containsmoż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 Containsużyje IEquatable<T>lub Equals()metoda, która może być pominięte.
Przypuszczam, że zależałoby to od typu, myCollectionktó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 ....