Potrzebuję przechowywać zestaw elementów. Co potrzebne jest funkcjonalnośćPobierz losowy element z C# HashSet szybko
- Usuń (single) elementów i
- add (zestawy) elementy i
- każdy obiekt powinien być dostępny tylko w zestawie raz
- dostać losowy element z ustawić
wybrałem HashSet (C#), ponieważ sport szybkich metod usuwania elementów (hashSet.remove (element)), dodawanie zestawów (hashSet.UnionWith (anotherHashSet)), a charakter programu HashSet gwarantuje, że nie ma duplikatów, więc zadbano o wymagania od 1 do 3.
Jedynym sposobem znalazłem się dostać element losowy jest
Object object = hashSet.ElementAt(rnd.Next(hashSet.Count));
Ale to jest bardzo powolny, ponieważ ja to nazywam raz dla każdego piksela mojej mapie (tworząc losowo Wypełnienie z wielu punktów wyjściowych; mapize 500x500 w tej chwili, ale chciałbym go powiększyć), a hashset zawiera raczej wiele elementów. (Szybki test pokazuje, że wysuwa się do 5752 wpisów przed ponownym zmniejszeniem.)
Profilowanie (próbkowanie procesora) mówi mi, że moje połączenia z ElementAt przejmują 50%.
Realizuję operacje 500x500 na dużym haszowaniu nie jest łatwym zadaniem, ale inne operacje (Remove i UnionWith) są wywoływane tak często, jak ElementAt, więc głównym problemem wydaje się być operacja, a nie liczba połączeń.
Niejasno rozumiem, dlaczego uzyskanie określonego elementu z HashSet jest bardzo kosztowne (w porównaniu do uzyskania go z listy lub innej uporządkowanej struktury danych, ale po prostu chcę losowy wybór Czy to naprawdę jest takie trudne i istnieje żaden sposób wokół niego? Czy istnieje lepsza struktura danych dla mojego celu?
Zmiana wszystko do list nie pomaga, bo teraz inne metody stają się wąskie gardła, a to trwa nawet dłużej.
Casting HashSet do array i wybierz mój losowy element z tego, co oczekiwane, nie pomaga, ponieważ podczas wybierania losowego elementu z tablicy jest szybki, casting hashset do tablicy w pierwszej kolejności zajmuje więcej czasu niż uruchomienie samego hashSet.ElementAt.
Jeśli chcesz lepiej zrozumieć, co próbuję zrobić: A link to my question and the answer.
Co usuwasz? Czy jest to tylko przypadkowo znaleziony element, czy jest on arbitralny? – spender
Dlaczego nie wszystkie twoje dodawanie i usuwanie za pomocą HashSet, a następnie zanim chcesz zrobić losowy piksel, wystarczy raz przekonwertować na listę? Użyj tej listy , a następnie wyrzuć ją. Chyba, że musisz dodawać, usuwać i otrzymywać losowe elementy w tym samym czasie ... –
Baldrick
@spender Usuwam przypadkowo znaleziony element tylko –