Perl - >避免不必要的方法调用

时间:2013-06-11 08:12:49

标签: perl

我必须阅读商店的日志文件。日志显示项目ID和后面的“已售出”字样。所以我制作了一个脚本来读取这个文件,计算出每个商品ID出现“售出”字数的次数。事实证明,这些物品有很多“所有者”。也就是说,“owner_id”(我的数据库中的数据)和“item_id”之间存在关系。我想知道每天有多少商品销售,所以我创建了一个“%item_id_owner_map”:

my %item_id_sold_times;
my %item_id_owner_map;

open my $infile, "<", $file_location or die("$!: $file_location");
while (<$infile>) {
    if (/item_id:(\d+)\s*,\s*sold/) {
        my $item_id = $1;
        $item_id_sold_times{$item_id}++;
        my $owner_ids =
          Store::Model::Map::ItemOwnerMap->fetch_by_keys( [$item_id] )
          ->entry();
        for my $owner_id (@$owner_ids) {
            $item_id_owner_map{$owner_id}++;
        }
    }
}
close $infile;

“Store :: Model :: Map :: ItemOwnerMap-&gt; fetch_by_keys([$ item_id]) - &gt; entry();” method将item_id或id作为输入,并将owner_id作为输出返回。

一切看起来都不错,但实际上,每次Perl找到正则表达式匹配时(也就是每次“if”条件适用),我的脚本都会调用“Store :: Model :: Map :: ItemOwnerMap-” &gt; fetch_by_keys“方法,这是非常昂贵的,因为这些日志文件非常长。

有没有办法让我的脚本更有效率?如果可能的话,我只想调用我的Model方法一次。

最佳!

1 个答案:

答案 0 :(得分:1)

将你的逻辑分成两个循环:

while (<$infile>) {
    if (/item_id:(\d+)\s*,\s*sold/) {
        my $item_id = $1;
        $item_id_sold_times{$item_id}++;
    }
}
my @matched_items_ids = keys %item_id_sold_times;
my $owner_ids =
  Store::Model::Map::ItemOwnerMap->fetch_by_keys( \@matched_item_ids )
  ->entry();
for my $owner_id (@$owner_ids) {
    $item_id_owner_map{$owner_id}++;
}

我不知道entry()调用是否正确,但该代码的一般形状应该适合您。

通常,数据库擅长获取行集,因此您最好尽量减少从数据库中获取的调用。