我应该使用什么集合来组合最快的密钥检索,以及 c# 中最快的排序枚举?
What collection should I use for combining fastest key retrieval, but also fastest sorted enumeration in c#?
有人可以向我推荐一些用于存储键值对的 C# 集合(或者提示我如何自己实现它),其中我将始终最多拥有 50 个这样的键值对。但通常只有 5-20 个键值对。而且我需要以绝对最快的速度检索给定键的值。首先我想到了 Dictionary,因为它的检索访问时间为 O(1)。但是我仍然不确定对这么小的集合使用字典的开销。但我想即使对于像这样的小型集合,Dictionary 也能提供最快的速度?
然后我还有另一个要求,我需要能够告诉给定键的下一个更大的键(例如,我有值为 2、4、6、8、10、11、12、15 和当我说让我们说 7 时,我需要能够快速分辨出下一个比 7 更大的键是 8)。所以我想到了把这些key集合起来排序,这样我就可以快速分出下一个更大的key)。当时我考虑过使用 SortedDictionary,但我发现,它的访问速度较慢 O(log(n)),但会为我提供找到下一个更大键的另一个好处。
顺便说一句,在整个使用过程中,这个集合永远不会被修改,它只需要在开始时构建,这可能会很慢,构建速度对我来说无关紧要它。我也根本不关心内存使用情况。
例如,我的解决方案也可以结合 Dictionary 和 SortedList。这将是 2 个集合的组合,只是为了最大限度地提高检索速度和“getNextBiggerKey”速度。
或者现在我也在考虑将 nextBiggerKey 存储在该键值对的值中。所以至少对于那些已经在集合中的密钥,它会给我下一个更大的密钥。
请问有没有人有什么好主意,如何在这种情况下完全最大化性能?
更新:我所说的键实际上是分数类型的。但是对于低值,分子和分母都不会大于 256,因此字节应该(很有可能)对它们都足够。
非常感谢您的帮助,我们将不胜感激:)
如果键实际上是一个整数,如您所示,则计算哈希来搜索元素没有任何优势(因此不需要对键进行哈希处理的集合)。由于您可以构建一次列表,然后就可以使用不可变列表,所以我认为二进制搜索是最快的。
我首先要尝试的是正常的 List<T>
键值对,用项目填充它,排序一次,然后使用 List.BinarySearch() 搜索元素。可以肯定的是,您应该对多个场景进行基准测试,但这无疑是一个好的开始。
此答案假设可能的密钥范围很小(最多几千个)。在这种情况下,您可以实施基于 lookup table 的解决方案。假设小数键的范围在 10 到 14 之间,包括二分之一和四分之一。还假设您在此范围内有 4 个键,值分别为 10、10 3/4、12 1/2 和 13。首先,您需要一种方法将键转换为将用作索引的整数数组。在这种情况下,翻译功能将是:
f(x) = (x - 10) * 4
因此键 10 被转换为索引 0,键 14 被转换为索引 16。接下来您需要构造一个长度为 17(从 0 到 16)的数组。下面的 table 显示了这个数组的值:
| 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 |
不,让我们使用这个数组进行一些搜索。
- 密钥12存在吗?我们应用翻译函数
(12 - 10) * 4
并得到索引 8。array[8]
的值是 10。10 不同于
8,所以密钥12不存在。
- 键 10 3/4 的下一个更大的键是什么?我们应用翻译函数并得到索引 3。
array[3]
是 3,所以密钥存在,但我们对此不感兴趣。我们需要查看下一个数组元素 array[4]
。它的值为 10,是密钥 12 1/4 的翻译。所以 10 3/4 的下一个更大的键是 12 1/4。
现在您已经有了按键搜索此结构的方法,您可以考虑如何将每个键与一个值相关联,以最终得到一个合适的字典。最简单的方法可能是在混合中添加另一个数组,长度相等,将每个键的值存储在同一索引中。
有人可以向我推荐一些用于存储键值对的 C# 集合(或者提示我如何自己实现它),其中我将始终最多拥有 50 个这样的键值对。但通常只有 5-20 个键值对。而且我需要以绝对最快的速度检索给定键的值。首先我想到了 Dictionary,因为它的检索访问时间为 O(1)。但是我仍然不确定对这么小的集合使用字典的开销。但我想即使对于像这样的小型集合,Dictionary 也能提供最快的速度?
然后我还有另一个要求,我需要能够告诉给定键的下一个更大的键(例如,我有值为 2、4、6、8、10、11、12、15 和当我说让我们说 7 时,我需要能够快速分辨出下一个比 7 更大的键是 8)。所以我想到了把这些key集合起来排序,这样我就可以快速分出下一个更大的key)。当时我考虑过使用 SortedDictionary,但我发现,它的访问速度较慢 O(log(n)),但会为我提供找到下一个更大键的另一个好处。
顺便说一句,在整个使用过程中,这个集合永远不会被修改,它只需要在开始时构建,这可能会很慢,构建速度对我来说无关紧要它。我也根本不关心内存使用情况。
例如,我的解决方案也可以结合 Dictionary 和 SortedList。这将是 2 个集合的组合,只是为了最大限度地提高检索速度和“getNextBiggerKey”速度。
或者现在我也在考虑将 nextBiggerKey 存储在该键值对的值中。所以至少对于那些已经在集合中的密钥,它会给我下一个更大的密钥。
请问有没有人有什么好主意,如何在这种情况下完全最大化性能?
更新:我所说的键实际上是分数类型的。但是对于低值,分子和分母都不会大于 256,因此字节应该(很有可能)对它们都足够。
非常感谢您的帮助,我们将不胜感激:)
如果键实际上是一个整数,如您所示,则计算哈希来搜索元素没有任何优势(因此不需要对键进行哈希处理的集合)。由于您可以构建一次列表,然后就可以使用不可变列表,所以我认为二进制搜索是最快的。
我首先要尝试的是正常的 List<T>
键值对,用项目填充它,排序一次,然后使用 List.BinarySearch() 搜索元素。可以肯定的是,您应该对多个场景进行基准测试,但这无疑是一个好的开始。
此答案假设可能的密钥范围很小(最多几千个)。在这种情况下,您可以实施基于 lookup table 的解决方案。假设小数键的范围在 10 到 14 之间,包括二分之一和四分之一。还假设您在此范围内有 4 个键,值分别为 10、10 3/4、12 1/2 和 13。首先,您需要一种方法将键转换为将用作索引的整数数组。在这种情况下,翻译功能将是:
f(x) = (x - 10) * 4
因此键 10 被转换为索引 0,键 14 被转换为索引 16。接下来您需要构造一个长度为 17(从 0 到 16)的数组。下面的 table 显示了这个数组的值:
| 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 |
不,让我们使用这个数组进行一些搜索。
- 密钥12存在吗?我们应用翻译函数
(12 - 10) * 4
并得到索引 8。array[8]
的值是 10。10 不同于 8,所以密钥12不存在。 - 键 10 3/4 的下一个更大的键是什么?我们应用翻译函数并得到索引 3。
array[3]
是 3,所以密钥存在,但我们对此不感兴趣。我们需要查看下一个数组元素array[4]
。它的值为 10,是密钥 12 1/4 的翻译。所以 10 3/4 的下一个更大的键是 12 1/4。
现在您已经有了按键搜索此结构的方法,您可以考虑如何将每个键与一个值相关联,以最终得到一个合适的字典。最简单的方法可能是在混合中添加另一个数组,长度相等,将每个键的值存储在同一索引中。