字典替代查找

时间:2012-05-24 17:29:47

标签: c# collections lookup-tables

我需要构建查找表。我使用Dictionary它包含45M长和45M int。密钥和int作为值。集合的大小是(45M * 12),其中long是8字节,int是4字节 大小约515 Mbyte。但事实上,进程的大小是1.3 GB。该过程仅包含此查找表。 Mat,是否有词典的替代?

THX

5 个答案:

答案 0 :(得分:3)

您愿意花多少钱? 你可以使用

KeyValuePair<long,int>[] table = new KeyValuePair<long,int> [45 M];

然后在第一列(long Key)上对此进行排序,并使用二进制搜索来查找您的值。

答案 1 :(得分:1)

你可以使用SortedList而不是Dictionary,它会提高内存效率,但可能会略微降低CPU效率,忽略测量内存的问题,以及为什么需要在1中首先加载如此多的数据:)< / p>

答案 2 :(得分:1)

字典有一个基础数组,它保存在数据上,但数组的大小必须大于你拥有的项目数,这就是字典查找速度的来源。实际上,底层数组的大小应该比项目数量(25 +%)大得多。结合这个事实,当你添加项目时,这个底层数组正在被重新分配和重新创建(为了使它更大)你可能有相当数量的内存准备好被垃圾收集(这意味着如果你真的需要更多的内存, GC会收回它,但由于你现在已经足够了,所以不会烦恼)。

这个字典是否会消耗比你可能允许的更多的内存,或者你只是好奇为什么它比你想象的要多?还有其他选项(其他答案和评论已经列出了一些),这些选项将使用更少的内存,但也会更慢。您是否遇到内存不足问题?

答案 3 :(得分:1)

如果您的范围限制为10 ^ 12的最大长值,则空间方面的问题是您必须使用long,因为您只需要比int可以容纳的位数多一些。如果是这样的话,你可以这样做: 将数据存储在512 Dictionary

的数组中
 var myData = new Dictionary<int,int>[512];

引用与long值相关联的int(在本例中我将其称为“key”),您将执行以下操作:

myData[key & 511].Add((int) (key >> 9), intValue);
int result = myData[(int) (key & 511)][(int) (key >> 9)];

您可能需要调整您创建的字典数量以及位摆设中使用的位数,以适应数据的真实约束。使用这种方法会将内存使用量减少大约三分之一

答案 4 :(得分:0)

另一种方法,假设数据是静态的:使用两个排序的数组 - 一个是long,一个是int。确保索引N中的项目在一个中是另一个中索引N处的键的值。使用Array.BinarySearch查找您要查找的关键值。