我有两个文件,每个文件都有以下结构:
Gjdfnsdmfn141kj4
Fsndfdksjf1lkfjf
fjdksfn2m1kd1jk2
cmvlkm2kljo4jojj
这意味着逐行排列具有相同长度的行。这两个文件的重量约为1GB,这意味着约有40亿行。
我想计算两个文件中存在的行数。
发生的第一个问题是内存超出,然后一次缓冲两个文件,等等。我的想法是比较单个数据块,让我们说100k行,然后将交集保存到输出数组,并擦除temp数组等。
我设法编写的(伪)代码是这样的:
$output = [];
$first = [];
$fh1 = fopen("file1.txt", "r");
while (!feof($fh1)) {
$first[] = fgets($fh1);
}
$chunk = 100000;
$fh2 = fopen("file2.txt", "r");
while (!feof($fh1)) {
$count = 0;
$lines = [];
while(!feof($fh1) && (++count == $chunk)) {
$lines[] = fgets($fh1);
}
intersection($fh1, $lines, $first);
}
function intersection($fh1, $lines, $first) {
$output = array_merge($output, array_intersect($lines, $first));
}
但它有点慢,似乎总是会产生空array_intersect
结果,并且只有在其中一个文件明显变小时才能工作。
我该如何以更好的方式做到这一点?
答案 0 :(得分:2)
我会先使用external sorting算法对文件进行排序。 PHP可能不是理想的,因此现有的工具会更好,但谷歌似乎也有一些人在PHP之前做过这样的例子。
然后您可以打开两个(已排序)文件并一起浏览它们以查找匹配项。你只需向前移动一直到你有一行将在另一行中的当前行之后,然后切换(如果两者显示相同的行,则输出)。这样你就可以获得所有匹配但只需要传递一次文件。