What.NET kolekcja zapewnia najszybsze wyszukiwanie

Mam 60K pozycji, które muszą być sprawdzone w porównaniu z listą 20K lookup. Czy istnieje obiekt kolekcji (jak List, HashTable) to zapewnia wyjątkowo szybką metodę Contains()? Czy będę musiał napisać swój własny? W otherwords, jest domyślną metodą Contains() po prostu Skanuj każdy element lub używa lepszego algorytmu wyszukiwania.

foreach (Record item in LargeCollection)
{
    if (LookupCollection.Contains(item.Key))
    {
       // Do something
    }
}

Uwaga . Lista odnośników jest już posortowana.

Author: Ondrej Janacek, 2009-06-17

8 answers

W najbardziej ogólnym przypadku, rozważ System.Collections.Generic.HashSet jako domyślna" zawiera " strukturę danych konia roboczego, ponieważ ocena Contains zajmuje stały czas.

Rzeczywista odpowiedź na "jaka jest najszybsza kolekcja do przeszukiwania" zależy od konkretnego rozmiaru danych, uporządkowanej ilości danych, kosztu hashowania i częstotliwości wyszukiwania.

 116
Author: Jimmy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 17:00:49

Jeśli nie potrzebujesz zamawiać, spróbuj HashSet<Record> (new to. Net 3.5)

Jeśli to zrobisz, użyj List<Record> i zadzwoń BinarySearch.

 63
Author: SLaks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-08 13:59:40

Rozważałeś List.BinarySearch(item)?

Powiedziałeś, że twoja duża kolekcja jest już posortowana, więc to idealna okazja? Hash byłby zdecydowanie najszybszy, ale powoduje to własne problemy i wymaga znacznie więcej kosztów na przechowywanie.
 20
Author: Mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-08 17:26:58

Powinieneś przeczytać Ten blog{[2] } że speed przetestował kilka różnych typów kolekcji i metod dla każdego z nich za pomocą technik jedno-i wielowątkowych.

Zgodnie z wynikami, BinarySearch na liście i SortedList były najlepszymi wykonawcami, którzy nieustannie biegali szyjka w szyję, gdy szukali czegoś jako "wartości".

Podczas korzystania z kolekcji, która pozwala na "klucze", Słownik, ConcurrentDictionary, Hashset i HashTables działały najlepiej ogólnie.

 8
Author: Do What You Love,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-27 07:23:35

Zachowaj obie listy x i y w posortowanej kolejności.

If X = y, wykonaj swojÄ… akcjÄ™, if x

Czas wykonania tego przecięcia jest proporcjonalny do min (size (x), size (y))

nie uruchamiaj .Pętla Contains () jest proporcjonalna do X * y, co jest znacznie gorsze.

 4
Author: clemahieu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-17 20:10:50

Jeśli możliwe jest sortowanie przedmiotów, istnieje znacznie szybszy sposób, aby to zrobić, a następnie wykonując wyszukiwanie kluczy w hashtable lub B-tree. Chociaż jeśli przedmioty nie są sortowalne, tak naprawdę nie możesz umieścić ich w drzewie B.

W każdym razie, jeśli sortowalne sortowanie obu list, to tylko kwestia chodzenia po liście wyszukiwania w kolejności.

Walk lookup list
   While items in check list <= lookup list item
     if check list item = lookup list item do something
   Move to next lookup list item
 3
Author: Rich Schuler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-17 19:51:28

Jeśli nie martwisz się o skrzypienie każdego ostatniego bitu wydajności, sugestia użycia HashSet lub wyszukiwania binarnego jest solidna. Twoje zbiory danych po prostu nie są wystarczająco duże, że będzie to problem 99% czasu.

Ale jeśli to tylko jeden z tysięcy razy masz zamiar to zrobić i wydajność jest krytyczna (i okazały się być nie do przyjęcia za pomocą HashSet / binary search), można z pewnością napisać własny algorytm, który chodził posortowane listy robi porównania jako poszedłeś. Każda lista będzie chodziła co najwyżej raz i w patologicznych przypadkach nie byłoby źle (po przejściu tej trasy prawdopodobnie okaże się, że porównanie, zakładając, że jest to ciąg znaków lub inna nieintegralna wartość, byłoby prawdziwym kosztem i że Optymalizacja będzie następnym krokiem).

 2
Author: Robert Horvick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-17 19:48:22

Jeśli używasz. Net 3.5, możesz zrobić czystszy kod używając:

foreach (Record item in LookupCollection.Intersect(LargeCollection))
{
  //dostuff
}
Nie mam tutaj. Net 3.5, więc jest to nieprzetestowane. Opiera się na metodzie rozszerzenia. Nie to, że LookupCollection.Intersect(LargeCollection) prawdopodobnie nie jest tym samym co LargeCollection.Intersect(LookupCollection) ... ten ostatni jest prawdopodobnie znacznie wolniejszy.

Zakłada się, że LookupCollection jest HashSet

 2
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-17 19:57:38