我必须阅读商店的日志文件。日志显示项目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方法一次。
最佳!
答案 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()
调用是否正确,但该代码的一般形状应该适合您。
通常,数据库擅长获取行集,因此您最好尽量减少从数据库中获取的调用。