我有以下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
}
答案 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的函数作为对象或类时,所有的赌注都是关闭的 - 你已经冒昧地冒险了。