寻找一些建议或洞察我认为PERL中的简单方法来比较文本文件。
让我们假设您有90,000个文本文件,它们的结构都相似,比如说它们有一个共同的主题,每个主题都有少量的唯一数据。
我的逻辑说只需循环遍历文件(为简单起见分为1000行),然后遍历#of文件... 90,000 - 然后再循环遍历90,000个文件以相互比较。这成为无数线路或流程的无限循环。
现在,此处的强制步骤是“删除”除我们正在处理的文件之外的任何文件中找到的任何行。最终目标是将所有文件清理为整个集合中唯一的内容,即使这意味着某些文件最终为空。
我说的是文件,但这可能是数据库中的行,也可能是数组中的元素。 (我已经尝试了所有。)到目前为止最快的解决方案是将所有文件加载到mysql中,然后运行 UPDATE表SET列= REPLACE(列,查找,替换);在使用mysql时也尝试了Parallel :: ForkManager。
最慢的方法实际上导致耗尽我的32 GB内存 - 将所有90k文件加载到阵列中。 90k文件根本没有用,像1000这样的小批量工作正常,但与其他89,000相比没有。
服务器规格如果有帮助:单核四核E3-1240 4Cores x 3.4Ghz w / HT 32GB DDR3 ECC RAM 1600MHz 1x256SSD
那么工程师如何解决这个问题呢?我只是PERL黑客...
答案 0 :(得分:2)
使用文件名(可能是行号)标记每一行,并使用Sort::External
对所有行进行排序。然后,您可以按顺序读取已排序的记录,并只在结果文件中写入一个唯一的行。
答案 1 :(得分:2)
如果你可以处理任意小的错误,那么Bloom过滤器是完美的。
引用维基百科:“布隆过滤器是一种节省空间的概率数据结构,用于测试元素是否是集合的成员。可能存在假阳性匹配,但错误否定不是;即查询返回要么“可能在集合中”,要么“绝对不在集合中”。“
本质上,您将使用k个哈希将每一行哈希到位阵列上的k个点。每次遇到新行时,如果k个散列索引中至少有一个为“0”位,则保证您没有看到它。您可以阅读Bloom过滤器,了解如何调整数组的大小,并选择k以使误报任意小。
然后浏览文件,删除获得肯定匹配的行,或将否定匹配行复制到新文件中。
答案 2 :(得分:0)
使用外部合并排序算法对项目进行排序,并在合并阶段删除重复项。
实际上,只需使用sort
标志调用-u
命令,就可以高效地执行此操作。来自Perl:
system "sort -u @files >output";
您的sort
命令可能会提供多个可调参数来改善其性能。例如,并行进程的数量或它可以分配的内存量。