我试图解析一个大的
@L_403_0@文件.我使用
@L_403_0@ :: SAX(使用Expat,而不是perl实现)读取它,并将所有第二级和下级节点放入我的“Node”类:
package Node; use Moose; has "name" => ( isa => "Str",reader => 'getName' ); has "text" => ( is => "rw",isa => "Str" ); has "attrs" => ( is => "rw",isa => "HashRef[Str]" ); has "subNodes" => ( is => "rw",isa => "ArrayRef[Node]",default => sub { [] } ); sub subNode { my ($self,$name) = @_; my $subNodeRef = $self->subNodes; my @matchingSubnodes = grep { $_->getName eq $name } @$subNodeRef; if (scalar(@matchingSubnodes) == 1) { return $matchingSubnodes[0]; } return undef; } 1;
在“end_element”子节点,我检查这是否是我关心的节点,如果是,我做一些进一步的处理.
这一切都对我的测试文件工作正常,但前天我把它抛在了我的真实文件,它的1300万行,它是永远的.它已经运行了36个多小时.如何判断是Moose还是XML :: SAX是瓶颈?麋鹿总是这么慢,还是我用错了?
更新在数据的20,000行子集上执行配置文件显示,Moose是瓶颈 – 特别是在Class :: MOP :: Class :: compute_all_applicable_attributes(13.9%)和其他类和Moose类中.
解决方法
虽然Moose在启动时做了很多工作,有时候会使它看起来有点慢,但它产生的代码,特别是像属性访问器这样的代码通常比平均Perl程序员可以写的快一些.所以给你的进程的运行时间是相当长的,我怀疑由Moose引起的任何开销都是相关的.
然而,从你所显示的代码中,我不能真正地告诉你什么是瓶颈,即使我坚信Moose不是.我还想指出,做__PACKAGE __-> Meta-> make_immutable,表示你现在已经“定稿”了,让Moose做了一些进一步的优化,但是我仍然怀疑这是什么导致你的麻烦.
您如何采取较小的数据样本,因此您的程序将在合理的时间内完成,并在分析器中查看,例如Devel::NYTProf
.这将能够告诉您程序中的哪个时间在哪里所以您可以优化这些部分,以获得最大的收益.
一种可能性是,您使用的类型约束相当慢.实际上验证实例属性对每一次对它们的写入访问(或类实例)都是一样的,这并不是大多数程序员通常会做的.您可以尝试使用更简单的约束,例如ArrayRef而不是ArrayRef [Node],如果您对数据的有效性足够确定.这样,只会检查属性值本身的类型,而不是该数组引用中每个元素的值.
但是,仍然要配置你的代码.不要猜