我需要存储一组元素。我需要的功能是:
- 删除(单个)元素,
- 添加(一组)元素,
- 每个对象只能在集合中出现一次,
- 从集合中获取一个随机元素。
我选择了 HashSet (C#),因为它具有快速的删除元素方法(hashSet.remove(element))、添加集合的方法(hashSet.UnionWith(anotherHashSet)),而 HashSet 的特性保证没有重复项,所以满足了要求1到3。
我找到的唯一获取随机元素的方式是:
Object object = hashSet.ElementAt(rnd.Next(hashSet.Count));
但这非常慢,因为我对地图的每个像素都调用一次它(从多个起始点创建随机泛洪;目前的地图大小为500x500,但我想扩大规模),并且哈希集保留了相当多的项。(快速测试表明,在缩小之前,它会增加到5752个条目。)
剖析(CPU采样)告诉我,我的ElementAt调用占据了50%以上。
我意识到在一个大哈希集上进行500x500次操作并不容易,但是其他操作(Remove和UnionWith)与ElementAt一样频繁,因此主要问题似乎是操作而不是调用数量。
我模糊地了解为什么从HashSet获取某个元素非常昂贵(与从列表或其他有序数据结构中获取相比,但我只想要随机选择。 它真的可以如此困难,并且没有其他方式吗? 是否有更好的数据结构适合我的目的?
将所有内容更改为List也无济于事,因为现在其他方法成为瓶颈,所需时间更长。
将HashSet转换为数组并从中选择我的随机元素预期不会有所帮助,因为虽然从数组中选择随机元素很快,但是首先将哈希集转换为数组比单独运行hashSet.ElementAt更慢。
如果您想更好地了解我的尝试,请访问: 我的问题和答案的链接。