基于大文件中的字符串求和权重



我很确定这里可能已经进行了修改/类似的讨论,但我想介绍我面临的确切问题以及我方可能的解决方案。然后我想听听你们的意见,什么是更好的方法,或者我如何才能认可我的逻辑。

问题我有一个很大的文件,里面有行。每行采用以下格式<weight>,<some_name>。现在我要做的是添加所有具有相同名称的对象的权重。问题是

  1. 我不知道some_name在文件中存在的频率有多高。它可能只出现一次,也可能是数百万人中的全部
  2. 没有订购
  3. 我正在使用文件流(特定于java,但这无关紧要)

解决方案1:假设我有一个巨大的ram,我计划做的是逐行读取文件,并在我的hash_map中使用名称key。如果已经存在,则将其相加,否则相加。它将花费我m ram(m=文件中的行数),但总体处理将是快速

解决方案2:假设我没有巨大的ram,我将分批进行。读取哈希表中的第一个10000,将其相加并转储到文件中。对文件的其余部分执行。处理完文件后,我将开始阅读处理过的文件,并重复这个过程来总结所有内容。

你们有什么建议?

除了你的建议,我可以对文件进行并行文件读取吗?我可以在这里访问FileInputStream,我可以使用FileInputStream来提高文件读取效率吗?

第二种方法对您没有帮助:为了产生最终输出,您需要足够的RAM来保存文件中的所有密钥,以及表示计数的单个Integer。无论你是要迈出一大步,还是一次迭代几次10K行,都不会改变你最终需要的占地面积。

有帮助的是以某种方式对键进行分区,例如通过键的第一个字符。如果名称以字母开头,请处理该文件26次,第一次只使用以'A'开头的键的权重,忽略所有其他键,第二次只使用'B' s,依此类推。这将使您最终得到26个不相交的文件。

另一种有效的方法是使用外部排序算法将无序文件转换为有序文件。这将允许您遍历有序的文件,边走边计算总数,并将它们写入输出,即使不需要内存中的表。

就优化I/O而言,我建议使用java.nio.file.Files类的newBufferedReader(Path path,Charset c)方法:它为您提供了一个针对读取效率进行优化的BufferedReader

执行此计算时文件是静态的吗?如果是这样,那么您可以根据名称对文件进行磁盘排序,并将连续的条目相加。

最新更新