我有2个(大)文件。第一个是大约200k行,第二个是大约3000万行。
我想使用Perl检查第一行中的每一行是否在第二行中。 将第一行的每一行直接与第二行的每一行进行比较是否更快,或者将它们全部存储在两个不同的数组中然后操作数组更好?
答案 0 :(得分:7)
您有文件A和文件B.您想检查文件A中的行是否出现在文件B中。
如果你有足够的内存来保存文件B的内容,每行使用一个条目,那么这是最简单的。来吧。
但是,如果不这样做,我建议您将这两个文件放在SQL数据库的表中。 SQLite可能就足够了。然后,您的问题将简化为简单JOIN
。如果行长度是个问题,请使用快速哈希,例如xxHash。如果实现正确,64位版本在64位计算机上速度非常快,特别是如果您在Perl中启用了优化。存储两列,哈希和实际行。如果哈希匹配,请检查线是否匹配。确保在哈希列上建立索引。
你说:
实际上,我的文件是这样的:文件A:名称编号(每行)文件B:名称日期位置编号(每行)我必须检查文件B是否包含与文件A的数据匹配的行(忽略日期)和位置例如)所以它不是完全匹配...
在这种情况下,你被设定了。你甚至不必担心哈希的东西(我将在这里留下参考)。在SQLite数据库的不同列中放置您需要匹配的有趣数据。写一个连接。 ......利润。
或者,您可以使用BerkeleyDB,这使您在将表存储在磁盘上时具有内存哈希的概念简单性。如果您有多个要匹配的属性,则无法很好地扩展。
答案 1 :(得分:1)
将第一个文件的行存储在散列中,然后遍历第二个文件而不将其存储在内存中。
存储第一个文件并迭代第二个文件可能违反直觉,反之亦然,但它允许您避免创建3000万元素哈希值。
use feature 'say';
my ($path_1, $path_2) = @ARGV;
open my $fh1,"<",$path_1;
my %f1;
$f1{$_} = $. while (<$fh1>);
open my $fh2,"<",$path_2;
while (<$fh2>) {
if (my $f1_line = $f1{$_}) {
say "file 1 line $f1_line appears in file 2 line $.";
}
}
请注意,如果不进行进一步处理,重复的行将按照它们在第二个文件中出现的顺序显示,而不是先显示。
此外,假设文件1没有重复的行,但必要时可以处理。