首先,如果有人问了这个问题,我想向您道歉。在没有找到如何计算散列引用数组的情况下搜索答案是困难的。
我的函数接收DBI查询的输出,这是一个包含电子邮件地址的散列引用数组。该任务是持有每日计数的电子邮件地址,按其域名。我所做的就是构建一个域的散列来计数。重点是该数组预计将存储至少10,000,000封电子邮件。运行该脚本需要几分钟时间。
问题是,你能想出一种简化算法的方法吗?
my ($data) = shift;
my %elements = ( );
foreach my $row (@$data)
{
my ($username, $domain) = split(/@/, $row->{addr});
if (exists($elements{$domain}))
{
$elements{$domain}++;
}
else
{
$elements{$domain} = 1;
}
}顺便说一下,我为我的英语感到抱歉,但我不是以英语为母语的人。谢谢。
发布于 2013-02-13 00:53:39
您不需要if/else逻辑。当您第一次尝试递增还不在散列中的键(在本例中是一个域)的计数时,Perl非常聪明地将计数设置为1。
去掉if,保留增量。你的效率可能不会有很大的提高,但你会得到一点。否则,循环就会变得尽可能紧凑。
发布于 2013-02-13 02:21:16
有一种优化方法可以使仅当字符串只包含一个@时为
(split /\@/, $string)[1]等同于,但效率低于
substr $string, 1 + index $string, '@'如果这行代码不经常执行,性能提升就不会那么显著,但在我刚刚运行的一个非常不科学的基准测试中,执行时间大致减半。
另一个区别是不存在@时的行为- split解决方案将给出undef,它将字符串设置为空字符串,但index解决方案将给出最后一个字符。
如果您不介意散列键中的前导@,您可以进一步提高效率:
substr $string, index $string, '@'发布于 2013-02-13 02:21:52
您的算法已经是O(N),这与计数算法的效率差不多。您可以进行微优化,例如删除if子句,但您不会获得任何算法改进。
https://stackoverflow.com/questions/14837534
复制相似问题