Perl:并行读取和处理多个文件

Perl : Reading and processing multiple files in parallel

我有一个文件(暂且称之为 enrolled_students.txt)需要用 Perl 阅读。该文件每行都有数据,因此需要参考其他文件以获取更多信息。

例如,主数据库会有名称和地址。但是根据每个人的国籍,我必须参考其他文件(按国家排序)才能找到匹配的姓名、国籍和家庭住址。

假设我有 100 个 name_of_country.txt 文件,我的 enrolled_students.txt 中有 10,000 行。我的问题是:

谢谢, 汉斯

我会将您的问题视为:如何高效地执行两个文件的 "join" 操作,这里是答案。

实际上Unix中有一个join命令。 http://linux.die.net/man/1/join

假设你有两个文件,student 和 student_with_country:

student: [name] [age] [...]
student_with_country: [name] [country] [...]

你可以做到:

join student student_with_country (by default, it will join based on the first field)

那么问题是如何通过使用多核使其更快?

答案是parallel命令。基本上,您可以 运行 一个简单的 map-reduce 程序使用它。例如,在这种情况下

cat student_with_country | parallel --block 10M --pipe join student - 

它将student_with_country 文件分成10M 块和运行 并行加入命令。这样,您就可以利用多核的力量。

您在此处尝试执行的操作类似于数据库引擎在将来自两个 table 的数据连接在一起时必须执行的操作。数据库引擎通常有许多不同的连接计划可供选择,它会尝试根据它对每个 table 中数据的了解来选择最好的一个。

同样适用于你。加入数据的方法有多种,最佳方法取决于每个输入文件的大小、是否预先排序等因素。

一些可能的方法:

  1. A 'Nested Loop',您可以在其中读取 enrolled_students.txt 文件的每一行,并针对其中的每一行遍历其他文件以找到匹配项。不太可能很快,如果文件太大而无法使用任何其他解决方案,您可能只会选择此选项。

  2. A 'Hash Join',您可以在其中将要连接的数据的一半(在您的示例中,可能是 name_of_country.txt)读取到由哈希索引的数据结构中.然后对于其他文件的每一行,您可以在散列中查找相应的行。这可以是相当高的性能,只要有足够的内存来同时存储两组数据中的至少一组。

  3. 如果两个文件都按某种排序顺序,根据相同的键排序,您也许可以使用 'Merge Join'。这是您同时从两个文件中读取行的地方,将记录匹配在一起就像拉链中的牙齿。

上面假设了一个简单的情况,其中有两个数据文件必须合并。您的问题涉及 100 个不同的 name_of_country.txt 文件,这可能会使事情复杂化。

关于您的第二个问题——您能否使用并行处理——这可能仅在处理受 CPU 约束时才有用。除非您发现它实际上是 CPU 绑定,否则可能无法保证生成分叉或线程解决方案的复杂性。

最后 - 如果您对同一数据进行多次分析 运行,建议将数据导入真实数据库并使用该 运行 查询。这将为您节省大量编码工作。