0

首先,如果有人问过这个问题,我想道歉。如果不知道如何计算散列引用数组,就很难找到答案

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

}

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

4

3 回答 3

1

您不需要 if/else 逻辑。Perl 足够聪明,可以在您第一次尝试增加尚未在散列中的键(在本例中为域)的计数时将计数设置为 1。

失去如果,保持增量。你可能不会在效率上获得巨大的提高,但你会得到一点点。否则,循环将尽可能紧密。

于 2013-02-12T16:53:39.490 回答
1

如果字符串仅包含一项,则可以进行一项优化@

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

等效于,但效率低于

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

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

另一个区别是 no@存在时的行为 -split解决方案将给出undef,它字符串化为空字符串,但index解决方案将给出最后一个字符。

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

substr $string, index $string, '@'
于 2013-02-12T18:21:15.817 回答
0

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

于 2013-02-12T18:21:51.653 回答