4

我有非常多的文件集合,我的任务是从这个集合中打开几个随机文件,将它们的内容视为一组整数并将其相交。

由于长时间将文件从磁盘读取到内存,这个过程非常慢,所以我想知道这个从文件读取的过程是否可以通过用一些“快速”语言重写我的程序来加速。目前我正在使用python,这对于这种工作可能效率低下。(如果我知道除了 python 和 javascript 之外的其他语言,我可以自己实现测试......)

将所有日期放入数据库是否有帮助?无论如何,文件都不适合 RAM,因此它将再次从磁盘读取,只有与数据库相关的开销。

文件的内容是长整数列表。90% 的文件非常小,不到 10-20MB,但剩下的 10% 大约是 100-200MB。作为输入 a 有文件名,我需要读取每个给定文件中存在的每个文件和输出整数。我试图将这些数据放在 mongodb 中,但这与基于普通文件的方法一样慢,因为我尝试使用 mongo 索引功能并且 mongo 不会将索引存储在 RAM 中。现在我只是剪切了 10% 的最大文件并将其余部分存储在 redis 中,有时会访问那些大文件。这显然是临时解决方案,因为我的数据会增长而可用的 RAM 量不会。

4

2 回答 2

3

您可以尝试的一件事是逐块计算文件的交集(即,从每个块将 x 字节读入内存,计算它们的交集,然后继续,最后计算所有交集的交集)。

或者,您可以考虑使用一些“重型”库来帮助您。考虑查看 PyTables(带有 HDF 存储)/使用 numpy 计算交叉点。这样做的好处是 HDF 层应该有助于处理不一次将整个数组结构保存在内存中的问题——尽管我之前没有尝试过这些工具中的任何一个,但它们似乎提供了你需要的东西。

于 2012-08-04T02:22:24.123 回答
1

如果没有文件包含重复的数字,我会试试这个:

sort file1 file2 | uniq -d

如果它们可能包含重复项,那么您需要先消除重复项:

sort -u file1 > /tmp/file1
sort -u file2 > /tmp/file2
cat /tmp/file1 /tmp/file2 | sort | uniq -d

或者,如果您更喜欢不(明确)使用临时文件的版本。

(sort -u file1; sort -u file2) | sort | uniq -d

你没有说文件的格式(上面假设文本,每行一个整数)。如果它们是某种二进制格式,在应用上述命令之前,您还需要一个命令来翻译它们。通过使用管道,您可以像这样组成此步骤:

(decode file1 | sort -u ; decode file2 | sort -u) | sort | uniq -d

decode是您必须编写的解析文件格式的程序的名称。

除了非常简短和简单之外,这个 shell 解决方案的好处是它可以处理任何大小的文件,即使它们不适合 RAM。

从您的问题中不清楚您是否有 2 个或任意数量的文件要相交(问题的开头是“一对”,结尾是“文件名列表”)。例如,要处理 5 个文件而不是 2 个文件,请使用uniq -c | awk '{ if ($1=="5") print $2; }'而不是uniq -d

于 2012-08-04T08:39:24.520 回答