我应该使用一个C#字典,如果我只需要快速查找键,并且值是不相关的?
我需要能够插入条目,然后能够快速确定是否已经插入条目的数据types。 Dictionary
似乎适合这种需要(见例)。 但是,我没有使用字典的values
。 我仍然应该使用字典还是有另一个更适合的数据types?
public class Foo { private Dictionary<string, bool> Entities; ... public void AddEntity(string bar) { if (!Entities.ContainsKey(bar)) { // bool value true here has no use and is just a placeholder Entities.Add(bar, true); } } public string[] GetEntities() { return Entities.Keys.ToArray(); } }
你可以使用HashSet<T>
。
HashSet<T>
类提供了高性能的集合操作。 一个集合是一个不包含重复元素的集合, 其元素没有特定的顺序 。
Habib的答案非常好,但对于multithreading环境(如果使用HashSet<T>
则必须使用lock
来保护对HashSet<T>
访问。 我发现自己更倾向于用lock
语句创build死锁。 另外, lock
每个Amdahl法则会产生更糟的加速,因为添加lock
语句会减less实际上并行的代码的百分比。
由于这些原因, ConcurrentDictionary<T,object>
符合multithreading环境中的法案。 如果你最终使用一个,然后像你在你的问题中包装它。 只是new
object
的价值,因为价值将不重要。 您可以validation其源代码中没有 。 lock
语句
如果你不需要集合的可变性,那么这将是没有意义的。 但是你的问题意味着你需要它,因为你有一个AddEntity
方法。
其他信息2017-05-19 – 实际上, ConcurrentDictionary
在内部使用锁,尽pipe本身并不lock
语句 – 它使用Monitor.Enter
(检查TryAddInternal
方法)。 但是,它似乎locking在字典中的单个桶,这意味着将整个事件放在lock
语句中的争用将更less。
总而言之, ConcurrentDictionary
对于multithreading环境通常更好。
实际上,使用Interlocked方法做一个并发散列集是非常困难的(不可能?)。 我自己试了一下,不断遇到需要同时修改两件事情的问题 – 一般来说只能locking。 我发现的一个解决方法是使用单链表对于散列桶,并且当一个线程需要在节点上操作而不受其他线程干扰时,有意在列表中创build循环; 这会导致其他线程在同一个地方被捕获,直到该线程完成了它的节点并且破坏了这个循环。 当然,它在技术上并没有使用锁,但它并没有很好地扩展。