Perl脚本澄清

时间:2014-12-05 23:32:07

标签: perl

我有以下perl脚本,并观察到第5行的语句需要30秒才能执行。我没有任何线索如何调查为什么花了那么多时间。

你能告诉我可能是什么原因吗?

sub parse {
   my $self = shift;
   my $parse_options = $self->get_options(@_);
   my $method = $self->can('_parse_systemid');
   return $method->($self, $parse_options->{Source}{SystemId});  # takes 30 s
}

1 个答案:

答案 0 :(得分:6)

您提供的代码:

sub parse {
   my $self = shift;
   my $parse_options = $self->get_options(@_);
   my $method = $self->can('_parse_systemid')
   return $method->($self, $parse_options->{Source}{SystemId});  # takes 30 s
}

可以重构为:

sub parse {
  my $self = shift;
  my $parse_options = $self->get_options(@_);
  return $self->_parse_systemid( $parse_options->{Source}{SystemId} ); # Still takes 30s.
}

在任何一种情况下,如果_parse_systemid不是$ self引用的对象的成员函数,则脚本会死亡,因此使用can可能是无用的。

无论如何,花费很长时间执行的代码在重构代码中仍然需要很长时间。这条线对你来说仍然是一个问题:

return $self->_parse_systemid( $parse_options->{Source}{SystemId} ); # Still takes 30s.

让我们重构一下只是为了让它更清晰:

my $systemid = $parse_options->{Source}{SystemId};
my $rv = $self->_parse_systemid( $systemid ); # Still takes 30s.
return $rv;

现在很清楚,花费30秒的是对$self->_parse_systemid()的调用。因此,您需要查看_parse_systemid引用的类$self方法中发生的情况。

调用Devel::NYTProf的帮助可能非常有用,这样您就可以深入了解_parse_systemid,看看在那里花了多长时间。

我们无法提供明确的答案,因为发布的代码不包含问题。因此,严格来说,这是一个无法回答的问题。但是,我相信这个答案中给出的建议会让你走上正轨。

更新:kjpirs在评论中提到了这一点,并且是正确的:_parse_systemid可能来自XML :: SAX :: PurePerl或XML :: LibXML :: SAX。按照惯例,以下划线开头的子例程旨在对类或对象私有。您的使用风险很大;当你使用不属于公共API的函数作为对象或类时,所有的赌注都是关闭的 - 你已经冒昧地冒险了。