【发布时间】:2014-07-09 17:48:12
【问题描述】:
我有一个简单的 Perl 脚本,它读取预期格式的文件,将一些相关信息保存到散列中,对散列进行一些操作,然后关闭文件并移动到下一个文件。
我需要考虑我的系统内存小于文件参数大小的情况,所以我想,为什么不试试呢?所以我将我的 VirtualBox 限制为 1GB 的 RAM,创建了一个 1.5GB 的列表,并将其作为输入提供给它。没有错误被抛出,它只是运行和运行。
我使用“free”命令查看了正在使用的系统内存,它显示近 99% 的内存正在使用,并且随着时间的推移完全没有增加。我的 Perl 脚本中有一些中断处理代码,当我按下它时,我的 vbox 变得无响应,我必须重新启动它。
我需要做的是输入几个格式如下的邮件列表
1-bob@bob.com
并向邮件列表中的每个电子邮件地址发送电子邮件。我通过将所有电子邮件地址添加到哈希中来跟踪它们。在处理每个地址时(即添加到哈希中),我还会对其进行验证并发送电子邮件给它(如果它是好的)。
有没有更好的方法来测试这个?我做错了吗?
use strict;
use warnings;
my %email_db;
while (<>) {
chomp;
my ($id, $email) = split /-/;
push @{ $email_db{$id} }, $email;
}
输入文件的预期数量可以从 1 到 5 不等(我在这里假设 - 问题并不具体),就文件大小给出的示例是 100MB 系统内存和 10GB 文件大小。末尾散列中的条目数未知。
散列的每个元素都有
key = unique ID
value = array of email addresses for that ID
【问题讨论】:
-
如果可以的话,将输入文件分成更小的部分,对适合系统内存的那些部分进行分析。将结果写入(序列化)到磁盘。最后整理这些结果。无论您的编程环境如何,请考虑类似 MapReduce 的过程:en.wikipedia.org/wiki/MapReduce
-
这不会解决您的问题,但您应该遍历
@ARGV的内容,除非您出于其他原因需要索引,所以for my $file (@ARGV) { .. }。使用split /-/而不是split("\055")(八进制 55 是 ASCII 连字符的代码点)。并使用open my $list_fh, '<', $file之类的词法文件句柄 -
答案在于曾经被评论的
#..do more stuff w/the info。就目前而言,您正在将文件中的所有数据读入哈希%email_db。除非您的算法允许增量处理数据,否则无法按照您的要求进行处理,但除非您解释需要做什么,否则我们无法为您提供帮助 -
@Borodin 我在问题中添加了“目标”部分,以向您展示需要做什么。该算法一点也不特别。我只是逐行解析文件,每一行都有一封电子邮件,我得到了电子邮件地址,我用电子邮件地址做事(参考编辑)。
-
@ScottJamesWalter:我已经修复了您的代码,假设您只需要阅读命令行上的所有文件,在这种情况下您不需要显式打开它们。如果已处理的电子邮件地址列表不适合内存,您必须以某种方式将其存储在磁盘上:那些说您“不允许这样做”的人必须允许一种可行的方法