【发布时间】:2011-04-24 07:47:04
【问题描述】:
我正在尝试解析一个大型 XML 文件。我使用 XML::SAX 阅读它(使用 Expat,而不是 perl 实现)并将所有二级及以下节点放入我的“节点”类:
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? Moose 总是这么慢,还是我用错了?
更新对 20,000 行数据子集进行分析表明,Moose 是瓶颈 - 特别是在 Class::MOP::Class::compute_all_applicable_attributes (13.9%) 和其他 Class和驼鹿类。
【问题讨论】:
-
驼鹿可能看起来很慢,但不要让他生气......
-
Class::MOP::Class::compute_all_applicable_attributes如果您不像我在回答中建议的那样__PACKAGE__->meta->make_immutable您的课程,则需要做很多事情。如果这样做,个人资料会如何变化? -
@Ether,那个是关于启动成本的。我的是关于运行成本,尤其是对象的创建和销毁。
-
我很想有一个你的 XML 数据的例子来测试它,我在 XML::Toolkit 中做了类似的事情(使用捆绑的 XML::Filter::Moose)并且会很好奇分析它。
-
您展示的代码相当短,为什么不使用传统的 perl5 对象重写它,看看它会如何改变呢?以非常信任的方式编写它,不检查任何类型约束或使用任何防御性编程实践。这将为您提供希望摆脱 perl 对象模型的速度上限