List <t> vs HashSet <t> - 动态集合选择是否有效?</t> </t>

时间:2013-11-07 20:30:41

标签: c# performance

var usedIds = list.Count > 20 ? new HashSet<int>() as ICollection<int> : new List<int>();

假设List在20个或更少的项目中性能更高,而HashSet在更高的项目数量(从this帖子)更高性能,是否有效的方法根据可预测的项目数量动态地使用不同的集合类型?

每种集合类型的所有操作都是相同的。

PS:我也发现HybridCollection Class似乎自动执行相同的操作,但我从未使用它,因此我也没有关于其性能的信息。

编辑:我的收藏主要用作具有许多插入和缓冲的缓冲区。

6 个答案:

答案 0 :(得分:3)

理论上,它可能取决于您在集合上执行的操作的数量和类型。在实践中,这种微观优化将证明增加复杂性是非常罕见的。

还要考虑您正在使用的数据类型。如果您使用int作为收集项目作为问题的第一行建议,那么阈值将远远小于20,其中List不再快于{{1}对于许多操作。

在任何情况下,如果你打算这样做,我会创建一个新的集合类来处理它,类似HybridDictionary的行,并用一些通用接口将它暴露给你的用户代码IDictionary的。

并确保对其进行分析以确保您的用例确实从中受益。

甚至可能有比这两个系列更好的选择,具体取决于你正在做什么。即如果您在插入和遍历之前或之后进行了大量操作,那么LinkedList可能会更适合您。

答案 1 :(得分:1)

HashSet用于更快的访问,但List用于插入。如果您不打算添加新项目,请使用HashSet,否则使用List。

答案 2 :(得分:1)

如果你的收藏非常小,那么表演几乎总是不会出现问题。如果你知道n总是小于20,那么根据定义,O(n)是O(1)。 Everything is fast for small n.

使用最合适的数据结构表示您在概念上处理数据的方式,您需要执行的操作类型以及应该最有效的操作类型。

答案 3 :(得分:1)

Hashset<T> Dictionary<K,T> 等广告素材可以更快地搜索和插入任何订单中的商品。

如果您始终拥有固定大小和大量索引操作,则最好使用

Arrays T[] 。由于c#中数组的协方差,将项添加到数组比添加到列表要慢。

List<T> 最适合用于索引操作的动态大小的集合。

我不认为编写类似混合集合的东西更好地使用取决于您的要求的集合。如果你有一个基于索引的操作的缓冲区我不会建议使用Hashtable,因为有人已经引用Hashtable设计使用更多的内存

答案 4 :(得分:0)

  

根据可预测的项目数量动态地使用不同的集合类型是否有效?

可以取决于“效率”的含义(MS为此提供HybridDictionary类,但遗憾的是它不是通用的)。但不管它的主要是是一个糟糕的选择。我会解释两者。

从效率的角度来看:

  1. List<T>中的添加总是会更快,因为HashSet<T>必须预先计算哈希码并存储它。尽管随着大小的增长,HashSet<T>的删除和查找速度会更快,但最后的结果是List<T>获胜。你必须决定哪一个对你更重要。

  2. HashSet<T>相比,
  3. List<T>会产生内存开销。 See this for some illustration

  4. 但是,从可用性的角度来看 它无需有意义。 HashSet<T>是一个集合,与List<T>的包不同。它们非常不同,它们的用途非常不同。为:

    1. HashSet<T>不能有重复项。

    2. HashSet<T>不关心任何订单。

    3. 因此,当您返回 hybrid ICollection<T>时,您的要求如下:“无论是否可以添加重复项都无关紧要。有时候会添加它,有时不会当然,迭代顺序并不重要“ - 很少有用。

      好q,+ +1。

答案 5 :(得分:-2)

HashSet更好,因为它可能会占用更少的空间,并且您可以更快地访问元素。