繁体   English   中英

我应该使用什么集合来组合最快的键检索,但也是 c# 中最快的排序枚举?

[英]What collection should I use for combining fastest key retrieval, but also fastest sorted enumeration in c#?

请有人向我推荐 c# 中的一些集合(或者也许是我自己实现它的提示)用于存储键值对,我将始终最多拥有 50 个这些键值对。 但通常只有 5-20 个键值对。 而且我需要绝对最快的检索给定键的值。 首先我想到了字典,因为它的检索访问时间为 O(1)。 但我仍然不确定为这么小的 collections 使用字典的开销。 但我猜即使对于像这样的小型 collections,Dictionary 也能提供最好的速度?

然后我有另一个要求,我需要能够告诉给定键的下一个更大的键(例如,我有值为 2、4、6、8、10、11、12、15 的键,当我说让我们说7,我需要能够快速判断,下一个比 7 更大的键是 8)。 于是想着把这些key的集合进行排序,这样就可以很快的分辨出下一个更大的key)。 我当时考虑使用 SortedDictionary,但我发现它的访问速度较慢 O(log(n)),但会为我提供寻找下一个更大密钥的另一个好处。

顺便说一句,通过这个集合的整个使用,它永远不会被修改,它只需要在开始时构建,这可能会很慢,对我来说构建它的速度无关紧要。 此外,我根本不关心 memory 的使用。

例如,我的解决方案也可以结合 Dictionary 和 SortedList。 将 2 个 collections 组合在一起,以最大限度地提高检索速度和“getNextBiggerKey”速度。

或者现在我也在考虑将 nextBiggerKey 存储在该键值对的值中。 因此,至少对于那些已经在收藏中的钥匙,它会给我下一个更大的钥匙。

那么有人有什么好主意吗,如何在这种情况下完全最大化性能?

更新:我所说的键实际上是分数类型的。 但是对于低值,分子和分母都不会大于 256,因此字节应该(很有可能)对它们都足够。

非常感谢您的帮助,将不胜感激:)

如果键实际上是 integer 如您所示,则计算 hash 来搜索元素没有任何优势(因此不需要散列键的集合)。 由于您可以构建一次列表,然后可以使用不可变列表,因此我认为二进制搜索是您可以获得的最快速度。

我首先要尝试的是 KeyValue 对的普通List<T> ,用项目填充它,对其进行一次排序,然后使用List.BinarySearch()搜索元素。 可以肯定的是,您应该对多个场景进行基准测试,但这肯定是一个好的开始。

这个答案假设可能的键范围很小(最多几千个)。 在这种情况下,您可以实现基于查找表的解决方案。 假设小数键的范围在 10 到 14 之间,包括一半和四分之一。 还假设您在此范围内有 4 个键,其值分别为 10、10 3/4、12 1/2 和 13。首先,您需要一种将键转换为 integer 的方法,该键将用作数组。 在这种情况下,翻译 function 将是:

f(x) = (x - 10) * 4

所以键 10 被转换为索引 0,键 14 被转换为索引 16。接下来您需要构造一个长度为 17(从 0 到 16)的数组。 下表显示了该数组的值:

|   Key   | Translated |  Index  |  Value  |
|---------|------------|---------|---------|
| 10      | 0          | 0       | 0       |
| 10 1/4  | 1          | 1       | 3       |
| 10 1/2  | 2          | 2       | 3       |
| 10 3/4  | 3          | 3       | 3       |
| 11      | 4          | 4       | 10      |
| 11 1/4  | 5          | 5       | 10      |
| 11 1/2  | 6          | 6       | 10      |
| 11 3/4  | 7          | 7       | 10      |
| 12      | 8          | 8       | 10      |
| 12 1/4  | 9          | 9       | 10      |
| 12 1/2  | 10         | 10      | 10      |
| 12 3/4  | 11         | 11      | 12      |
| 13      | 12         | 12      | 12      |
| 13 1/4  | 13         | 13      | -1      |
| 13 1/2  | 14         | 14      | -1      |
| 13 3/4  | 15         | 15      | -1      |
| 14      | 16         | 16      | -1      |

不,让我们使用这个数组进行一些搜索。

  1. 密钥 12 存在吗? 我们应用翻译 function (12 - 10) * 4得到索引 8。 array[8]的值是 10。10 与 8 不同,因此键 12 不存在。
  2. 10 3/4 键的下一个更大的键是什么? 我们应用翻译 function 并得到索引 3。 array[3]为 3,因此键存在,但我们对此不感兴趣。 我们需要查看下一个数组元素, array[4] 它的值为 10,它是键 12 1/4 的翻译。 所以下一个更大的 10 3/4 键是 12 1/4。

现在您已经有了一种按键搜索此结构的方法,您可以考虑如何将每个键与一个值相关联,最终得到一个正确的字典。 最简单的方法可能是在混合中添加另一个长度相等的数组,将每个键的值存储在同一索引中。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM