Мне нужно сохранить набор элементов. Мне нужна функциональность для
- удалить (одиночные) элементы и
- добавить (множество) элементов и
- каждый объект должен быть установлен только один раз и
- получить случайный элемент из набора
Я выбрал HashSet (С#), так как он поддерживает быстрые методы для удаления элементов (hashSet.remove(element)), добавление наборов (hashSet.UnionWith(anotherHashSet)) и характер HashSet гарантирует, что дубликатов нет, поэтому соблюдаются требования 1-3.
Единственный способ получить случайный элемент -
Object object = hashSet.ElementAt(rnd.Next(hashSet.Count));
Но это очень медленно, так как я назову его один раз для каждого пикселя моей карты (создавая случайную заливку заливки из нескольких начальных точек, на данный момент отображает 500x500, но я хотел бы увеличить), а hashset многие предметы. (Быстрый тест показывает, что он дует до 5752 записей, прежде чем снова сжиматься.)
Профилирование (выборка процессора) говорит мне, что мои вызовы ElementAt занимают более 50%.
Я понимаю, что операции 500x500 по большому hashset - непростая задача, но другие операции (Remove and UnionWith) вызываются так же часто, как ElementAt, поэтому основной проблемой является операция, а не количество вызовов.
Я смутно понимаю, почему получение определенного элемента из HashSet очень дорого (по сравнению с его получением из списка или другой упорядоченной структуры данных, но я просто хочу случайный выбор. Неужели это действительно так сложно и нет ли способа обойти это? Есть ли лучшая структура данных для моей цели?
Изменение всего на Списки не помогает, потому что теперь другие методы становятся узкими местами, и это занимает еще больше времени.
Отбрасывание HashSet в массив и выбор моего случайного элемента из него, как ожидается, не поможет, потому что, когда выбор случайного элемента из массива выполняется быстро, наложение хэш-набора на массив в первую очередь занимает больше времени, чем запуск hashSet.ElementAt само по себе.
Если вы хотите лучше понять, что я пытаюсь сделать: Ссылка на мой вопрос и ответ.