perl - 为什么 Moose 代码这么慢?

标签 perl sax moose

我正在尝试解析一个大型 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?驼鹿总是这么慢,还是我用错了?

更新 对 20,000 行数据子集进行分析表明,瓶颈是 Moose - 特别是在 Class::MOP::Class::compute_all_applicable_attributes (13.9%) 和其他 Class 和 Moose 类中。

最佳答案

虽然 Moose 在启动时做了很多工作,有时会显得有点慢,但它生成的代码,尤其是属性的访问器之类的东西,通常比普通 perl 程序员能够编写的要快得多。因此,考虑到您的流程的运行时间很长,我怀疑 Moose 引起的任何开销是否相关。

但是,从您展示的代码中,我无法确定您的瓶颈是什么,尽管我坚信它不是 Moose。我还想指出,做__PACKAGE__->meta->make_immutable , 声明你的类(class)现在已经“完成”允许 Moose 做一些进一步的优化,但我仍然怀疑这就是给你带来麻烦的原因。

您如何取较小的数据样本,以便您的程序在合理的时间内完成,然后在分析器(例如 Devel::NYTProf )中查看该数据。 .这将能够告诉您程序中的时间究竟花在哪里,因此您可以专门优化这些部分以获得最大可能的 yield 。

一种可能性是您使用的类型约束使事情变慢了很多。实际上,在对它们的每次写访问(或在类实例化)上彻底验证实例属性,并不是大多数程序员通常会做的事情。您可以尝试使用更简单的约束,例如 ArrayRef而不是 ArrayRef[Node] ,如果您对数据的有效性有足够的把握。这样,只会检查属性值本身的类型,而不是该数组引用中每个元素的值。

但是,仍然要分析您的代码。别猜了。

关于perl - 为什么 Moose 代码这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3915062/

相关文章:

perl - 如何使用与主脚本在同一文件中定义的 Moose 类?

Perl 的 tr///没有做我想做的事

子类中的 perl moose 触发器破坏方法修饰符

perl - 如何以 Mooseish 方式声明 2 个依赖属性?

Perl:动态模块加载、对象继承和 "common helper files"

regex - 如何使用 Perl 解析 runmqsc 命令输出?

java - 在 Java 中,如何使用 SAX 解析器评估 XML 上的 XPATH 表达式?

java - Android 中的 SAX XML 解析

c# - 将模板与 OpenXML 和 SAX 结合使用

perl - 从 Moose 中的属性名称动态生成写入器/读取器