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

假设 List 在 20 个或更少的项目上性能更高,而 HashSet 在项目数量更大的情况下性能更高(来自这篇文章),根据可预测的项目数动态使用不同的集合类型是有效的方法吗?

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

PS:我还发现了 HybridCollection类,它似乎自动做同样的事情,但我从未使用过它,所以我也没有关于它的性能的信息。

编辑:我的集合主要用作具有许多插入和获取的缓冲区。

4

6 回答 6

3

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

还要考虑您正在使用的数据类型。如果您int按照问题的第一行所建议的那样使用集合项,那么阈值将大大小于 20,List这不再比HashSet许多操作快。

无论如何,如果您要这样做,我将创建一个新的集合类来处理它,类似于HybridDictionary的内容,并使用一些通用接口(如 IDictionary)将其公开给您的用户代码。

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

甚至可能有比这些集合中的任何一个更好的选择,具体取决于您正在做什么。即,如果您正在执行大量“之前或之后”插入和遍历,那么LinkedList可能对您更有效。

于 2013-11-07T20:43:50.740 回答
1

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

于 2013-11-07T20:34:30.650 回答
1

如果您的收藏非常小,那么性能几乎总是不成问题。如果你知道 n 总是小于 20,根据定义,O(n) 就是 O(1)。 对于小 n,一切都很快。

使用最合适的数据结构来代表您在概念上如何处理数据、您需要执行的操作类型以及应该最有效的操作类型。

于 2013-11-07T20:57:08.220 回答
1

哈希表喜欢Hashset<T>并且Dictionary<K,T>在以任何顺序搜索和插入项目时更快。

Arrays T[]如果您始终具有固定大小和大量索引操作,则最好使用。由于 c# 中数组的协方差,将项目添加到数组比添加到列表要慢。

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

我认为编写混合集合之类的东西不是一个好主意,最好根据您的要求使用集合。如果您有一个带有大量基于索引的操作的缓冲区,我不建议使用 Hashtable,因为有人已经通过设计引用了 Hashtable 使用更多内存

于 2013-11-07T21:53:25.250 回答
0

is it efficient approach to use different collection types dynamicaly based on the predictable items count?

It can be depending on what you mean by "efficiency" (MS offers HybridDictionary class for that, though unfortunately it is non generic). But irrespective of that its mostly a bad choice. I will explain both.

From an efficiency standpoint:

  1. Addition will be always faster in a List<T>, since a HashSet<T> will have to precompute hash code and store it. Even though removal and lookup will be faster with a HashSet<T> as size grows up, addition to the end is where List<T> wins. You will have to decide which is more important to you.

  2. HashSet<T> will come up with a memory overhead compared to List<T>. See this for some illustration.

But however, from a usability standpoint it need not make sense. A HashSet<T> is a set, unlike a bag which List<T> is. They are very different, and their uses are very different. For:

  1. HashSet<T> cannot have duplicates.

  2. HashSet<T> will not care about any order.

So when you return a hybrid ICollection<T>, your requirement goes like this: "It doesn't matter whether duplicates can be added or not. Sometimes let it be added, sometimes not. Of course iteration order is not important anyway" - very rarely useful.

Good q, and +1.

于 2014-05-29T14:39:14.903 回答
-2

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

于 2013-11-07T20:57:17.360 回答