下面给出的信息(线条)似乎不够明确,所以我试图更清晰简洁。
我需要建议如何将数十亿的ulong值映射到几个int值。在最坏的情况下,我有超过110亿(基本上是随机的ulong值),需要映射到40个int值。映射是已知的,除了所需的内存量之外,字典也可以工作。目前,估计在使用字典时,大约199GB的RAM将用于所有需要的映射。
有没有人知道可以用来完成这种映射的任何类型的算法或过程而不消耗这么多RAM?
我正在开发一个C# - .NET 4.5程序,以帮助过滤我的数据并遇到效率问题。我目前正在通过8(我最终需要做20个)不同的过滤器运行我的数据,每个过滤器以相同的方式过滤数据,但是在不同的级别。在过滤器过程中的某个点,每个级别都有许多必须编码到最终输出值的值。
一些例子:
在第3级,有23个值被编码为6个可能的输出值(0-5)。
在第7级,有2,576个值被编码为14个可能的输出值(0-13)。
在10级,有88,215个值被编码成20个可能的输出值(0-19)。
当我达到20级时,我将有超过11个BILLION值被编码为40个输出值(0-39)。
每个过滤器要编码的值都是事先已知的,我正在从文件中读取此信息,并为每个过滤器填充单独的字典(当前为1到8)。按照这个速度,当我进入过滤器20时,将有超过16.5亿个字典条目,其中大部分都是ulong值。
从长远来看,这不是一个解决方案。
有没有人知道如何更有效地将数百万个唯一输入值映射到一些独特的输出值?
是否有将输入映射到输出的算法?
我正在寻找可能指向正确方向的任何想法。
答案 0 :(得分:1)
如果对输入CSV文件中的值进行排序,并且数据永远不会更改,我们可以从注释中放弃存储桶方法,只需将所有数据对填入文件中的一个大数组中。目标是使数据更好地组织,以实现快速阅读,从而避免在内存中使用整个数据集。您必须将CSV文件转换为新的二进制格式,并在此过程中在内存中创建索引数组。此索引数组也应保存到某个索引文件中,以便在重新启动程序时使用它。在内存中,您只能保存第一个数据对的位置数组,其值以项目索引开头。在文件中,您将只有一个大量的32位(4字节)数字,其中每个数字的前3个字节是内存中索引项的剩余部分,最后一个字节是我们的输出。
要创建索引数组,您将逐行读取CSV文件。对于每个数据表(input_int
,output_int
),请创建新的数据表(index
,32-bit value
)。 Index
占用input_int
的前2个字节,并创建32-bit value
连接input_int
的最后3个字节和output_int
的唯一字节。如果index
从以前的数据表中更改,则将文件的位置存储到新索引处的数组。无论如何,将32-bit value
附加到文件中。重复直到CSV文件结束。
所以假设我们有一个输入值0x1234567890,需要相应的输出值。算法会在内存中找到索引为0x1234和0x1235的项目。这将为您提供项目所在文件中的开始和结束位置。在此范围内,我们为值0x567890执行binary search并获取其后的字节。这是我们的产值。