如何提高域名计数算法的效率?

时间:2013-02-12 16:48:27

标签: arrays algorithm perl complexity-theory hash

首先,如果有人提出这个问题,我想道歉。很难找到答案,无法找到如何计算哈希引用数组

我的函数接收来自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;
    }

}

顺便说一下,我对我的英语很抱歉,但我不是母语人士。感谢。

3 个答案:

答案 0 :(得分:1)

您不需要if / else逻辑。 Perl非常聪明,可以在第一次尝试增加一个尚未在哈希中的密钥(在这种情况下是一个域)的计数时将计数设置为1。

丢失if,保持增量。你可能不会大幅度提高效率,但你会得到一点点。否则,循环就像它真正得到的那样紧。

答案 1 :(得分:1)

您可以进行一项优化 iff 该字符串只包含一个@

(split /\@/, $string)[1]

相当于,但效率低于

substr $string, 1 + index $string, '@'

如果该行不经常执行,性能提升不会那么显着,但在我刚刚运行的非常不科学的基准测试中,执行时间大致减半。

如果不存在@,则另一个区别是行为 - split解决方案会提供undef,这会将字符串化为空字符串,但index解决方案会给出最后一个角色。

如果您不介意哈希键中的前导@,则可以进一步提高效率:

substr $string, index $string, '@'

答案 2 :(得分:0)

你的算法已经是O(N),它与计数算法的效率差不多。您可以进行微优化,例如消除if子句,但是您不会得到任何算法改进。