Próbuję ogarnąć głowę, które struktury danych są najbardziej wydajne i kiedy / gdzie ich użyć.
Możliwe, że po prostu nie rozumiem struktur wystarczająco dobrze, ale czym ILookup(of key, ...)
różni się od Dictionary(of key, list(of ...))
?
Również gdzie chciałbym użyć ILookup
i gdzie byłoby to bardziej wydajne pod względem szybkości programu / pamięci / dostępu do danych itp.?
Odpowiedzi:
Dwie istotne różnice:
Lookup
jest niezmienna. Tak :) (Przynajmniej uważam, że konkretnaLookup
klasa jest niezmienna, aILookup
interfejs nie zapewnia żadnych mutujących elementów członkowskich. Oczywiście mogą istnieć inne modyfikowalne implementacje.)KeyNotFoundException
. (Dlatego nie maTryGetValue
, AFAICR.)Prawdopodobnie będą one równoważne pod względem wydajności - na przykład wyszukiwanie może korzystać
Dictionary<TKey, GroupingImplementation<TValue>>
zza kulis. Wybierz między nimi w zależności od swoich wymagań. Osobiście uważam, że wyszukiwanie jest zwykle lepiej dopasowane niż aDictionary<TKey, List<TValue>>
, głównie z powodu dwóch pierwszych punktów powyżej.Należy pamiętać, że jako szczegółów realizacji, konkretna realizacja
IGrouping<,>
, który jest używany dla wartości narzędziIList<TValue>
, co oznacza, że jest wydajny w użyciuCount()
,ElementAt()
etc.źródło
Ciekawe, że nikt nie określił rzeczywistej największej różnicy (pobrane bezpośrednio z MSDN ):
źródło
Zarówno a, jak
Dictionary<Key, List<Value>>
i aLookup<Key, Value>
logicznie mogą przechowywać dane zorganizowane w podobny sposób i oba mają tę samą wydajność. Główną różnicą jest to, że aLookup
jest niezmienny: nie maAdd()
metod ani publicznego konstruktora (i jak wspomniał Jon, można bez wyjątku zapytać o nieistniejący klucz i mieć klucz jako część grupowania).To, którego używasz, naprawdę zależy od tego, jak chcesz ich używać. Jeśli utrzymujesz mapę klucza do wielu wartości, która jest stale modyfikowana,
Dictionary<Key, List<Value>>
to prawdopodobnie jest lepsze, ponieważ jest zmienne.Jeśli jednak masz sekwencję danych i potrzebujesz tylko widoku tylko do odczytu uporządkowanych według klucza, wyszukiwanie jest bardzo łatwe do skonstruowania i daje migawkę tylko do odczytu.
źródło
Podstawowa różnica między
ILookup<K,V>
a aDictionary<K, List<V>>
polega na tym, że słownik jest zmienny; możesz dodawać lub usuwać klucze, a także dodawać lub usuwać elementy z przeszukiwanej listy.ILookup
Jest niezmienne i nie mogą być zmienione po utworzeniu.Podstawowa implementacja obu mechanizmów będzie taka sama lub podobna, więc ich szybkość wyszukiwania i zużycie pamięci będą w przybliżeniu takie same.
źródło
Inną różnicą, o której jeszcze nie wspomniano, jest to, że Lookup () obsługuje klucze puste :
źródło
Jeśli wyjątek nie jest opcją, przejdź do Lookup
Jeśli próbujesz uzyskać strukturę tak wydajną jak a,
Dictionary
ale nie wiesz na pewno, że nie ma zduplikowanego klucza w danych wejściowych,Lookup
jest bezpieczniejsze.Jak wspomniano w innej odpowiedzi, obsługuje również klucze o wartości null i zwraca zawsze prawidłowy wynik podczas odpytywania z dowolnymi danymi, więc wydaje się być bardziej odporny na nieznane dane wejściowe (mniej podatny niż słownik na zgłaszanie wyjątków).
A jest to szczególnie prawdziwe, jeśli porównasz to z
System.Linq.Enumerable.ToDictionary
funkcją:Alternatywą byłoby napisanie własnego zduplikowanego kodu zarządzania kluczami wewnątrz
foreach
pętli.Uwagi dotyczące wydajności, słownik: wyraźny zwycięzca
Jeśli nie potrzebujesz listy i zamierzasz zarządzać ogromną liczbą elementów
Dictionary
(lub nawet własną niestandardową strukturą), byłoby bardziej wydajne:Ponieważ
Lookup
musi utrzymywać listę elementów dla każdego klucza, jest wolniejszy niż słownik (około 3x wolniejszy w przypadku dużej liczby elementów)źródło