简体   繁体   English

使用字典 <Foo, Foo> 而不是列表 <Foo> 加快召唤包含()

[英]Using Dictionary<Foo, Foo> Instead of List<Foo> to Speed up Calls to Contains()

I have a question about generic collections in C#. 我对C#中的泛型集合有疑问。 If I need to store a collection of items, and I'm frequently going to need to check whether an item is in the collection, would it be faster to use Dictionary instead of List? 如果我需要存储一组项目,并且我经常需要检查项目是否在集合中,那么使用Dictionary而不是List会更快吗?

I've heard that checking if an item is in the collection is linear relative to the size for lists and constant relative to the size for dictionaries. 我听说检查一个项目是否在集合中是相对于列表大小是线性的还是相对于字典大小的常量。 Is using Dictionary and then setting Key and Value to the same object for each key-value pair something that other programmers frequently do in this situation? 是否正在使用Dictionary,然后将Key和Value设置为每个键值对的同一对象,这是其他程序员在这种情况下经常做的事情?

Thanks for taking the time to read this. 感谢您抽时间阅读。

Yes, yes it is. 是的,是的。 That said, you probably want to use HashSet because you don't need both a key and a value, you just need a set of items. 也就是说,您可能希望使用HashSet因为您不需要键和值,只需要一组项。

It's also worth noting that Dictionary was added in C# 2.0, and HashSet was added in 3.5, so for all that time inbetween it was actually fairly common to use a Dictionary when you wanted a Set just because that was all you had (without rolling your own). 同样值得注意的是,在C#2.0中添加了Dictionary ,并且在3.5中添加了HashSet ,所以在中间的所有时间内,当你想要一个Set时,使用一个词组实际上是相当常见的,因为那是你所拥有的(没有滚动你的拥有)。 When I was forced to do this I just stuck null in the value, rather than the item as the key and value, but the idea is the same. 当我被迫这样做时,我只是在值中加入null,而不是将项目作为键和值,但这个想法是一样的。

Just use HashSet<Foo> if what you're concerned with is fast containment tests. 如果你关注的是快速包容测试,只需使用HashSet<Foo>

A Dictionary<TKey, TValue> is for looking a value up based on a key. Dictionary<TKey, TValue>用于根据键查找值。

A List<T> is for random access and dynamic growth properties. List<T>用于随机访问和动态增长属性。

A HashSet<T> is for modeling a set and providing fast containment tests. HashSet<T>用于对集合进行建模并提供快速包含测试。

You're not looking up a value based on a key. 您没有根据密钥查找值。 You're not worried about random access, but rather fast containment checks. 您不担心随机访问,而是快速控制检查。 The right concept here is a HashSet<T> . 这里正确的概念是HashSet<T>

Assuming that there is only ever one copy of the item in the list, then the appropriate data structure is ISet<T> , specifically HashSet<T> . 假设列表中只有一个项目的副本,那么适当的数据结构是ISet<T> ,特别是HashSet<T>

That said, I've seen timing that indicate that a Dictionary<TKey, TValue> ContainsKey call is a wee bit faster than even HashSet<T> . 也就是说,我已经看到时间表明Dictionary<TKey, TValue> ContainsKey调用比HashSet<T>快一点。 Either way, both of them are going to be loads faster than a plain List<T> lookup. 无论哪种方式,它们都将比普通的List<T>查找更快地加载。

Keep in mind that both of these methods (HashSet and Dictionary) rely on reasonably well-implemented Equals and GetHashcode implementations for T . 请记住,这两种方法(HashSet和Dictionary)都依赖于T合理良好实现的Equals GetHashcode实现。 List<T> only relies on Equals List<T>仅依赖于Equals

字典或HashSet将使用更多内存,但提供(几乎)O(1)搜索时间。

您可能希望查看HashSet ,它是唯一对象的集合(只要该对象实现IEquality比较器)。

You mention using List<T> , which implies that ordering may be important. 您提到使用List<T> ,这意味着排序可能很重要。 If this is the case then you may also want to look into the SortedSet<T> type as well. 如果是这种情况,那么您可能还想查看SortedSet<T>类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 转换字典 <string,List<foo> &gt;列表 <foo> 在C#2.0中 - Convert Dictionary<string,List<foo>> to List<foo> in C# 2.0 如果我有一个类A,其字段foo是一个Dictionary,那么如何使用foo作为数据集快速使A实现IDictionary? - If I have a class A with a field foo that is a Dictionary, how can I make A implement IDictionary quickly using foo as dataset? 使用“ ObjectList.Contains(foo)”时,对象列表无法正确比较 - List of objects wont compare correctly when using “ObjectList.Contains(foo)” 在VB.NET中使用Dim foo As Foo有什么问题吗? - Are there issues using Dim foo As Foo in VB.NET? DOTween 使用 Append(Tween) 代替 AppendCallback(()=&gt; foo()) - DOTween use Append(Tween) instead AppendCallback(()=> foo()) 参数字典包含用于方法的非空类型&#39;System.Int32&#39;的参数&#39;foo&#39;的空条目 - The parameters dictionary contains a null entry for parameter 'foo' of non-nullable type 'System.Int32' for method 无法从List <Bar>转换为List <Foo> - Cannot convert from List<Bar> to List<Foo> IFoo foo = new Foo()和Foo foo = new Foo()有什么区别 - What is the difference between IFoo foo = new Foo() and Foo foo = new Foo() 转换字典的最简单方法 <int, Dictionary<int, Foo> &gt;到IEnumerable <IEnumerable<Foo> &gt;在Linq? - Simpliest way to transform a Dictionary<int, Dictionary<int, Foo> > to IEnumerable<IEnumerable<Foo> > in Linq? 带功能的最小起订量<Foo, Task<List<Bar> &gt;&gt;&gt; - Moq with Func<Foo, Task<List<Bar>>>>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM