Почему код Moose такой медленный? - PullRequest
9 голосов
/ 12 октября 2010

Я пытаюсь разобрать большой файл XML.Я прочитал его, используя XML :: 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" япроверьте, является ли этот узел мне небезразличным, и если это так, я делаю некоторую дальнейшую обработку.

Это все работало нормально на моих тестовых файлах, но позавчера я бросил его на свой настоящий файл, все13 миллионов строк, и это займет вечность.Он работает более 36 часов.Как я могу сказать, что узким местом является Moose или XML :: SAX?Лось всегда такой медленный или я неправильно его использую?

Обновление Выполнение профиля на подмножестве данных в 20 000 строк показывает, что узким местом является Moose, в частности в Class :: MOP :: Class :: compute_all_applicable_attributes (13,9%) идругие классы и лося.

Ответы [ 3 ]

22 голосов
/ 12 октября 2010

Хотя Moose довольно долго работает во время запуска, что иногда делает его немного медленным, генерируемый им код, особенно такие, как средства доступа к атрибутам, как правило, немного быстрее, чем это может сделать обычный программист на Perl. написать. Поэтому, учитывая, что время выполнения вашего процесса довольно продолжительное, я сомневаюсь, что любые накладные расходы, вызванные Moose, будут актуальны.

Однако, из кода, который вы показали, я не могу точно сказать, что вы узкое место, хотя я твердо верю, что это не Moose. Я также хочу отметить, что выполнение __PACKAGE__->meta->make_immutable, чтобы заявить, что ваш класс теперь "завершен", позволяет Moose провести дальнейшую оптимизацию, но все же я сомневаюсь, что это вызывает у вас проблемы.

Как насчет того, чтобы взять небольшую выборку ваших данных, чтобы ваша программа закончила в разумные сроки, и посмотрите на это в профилировщике, таком как Devel::NYTProf. Это позволит вам определить, сколько именно времени в вашей программе тратится, поэтому вы можете оптимизировать именно эти части, чтобы получить максимально возможный выигрыш.

Одна из возможностей заключается в том, что используемые вами типы ограничений замедляют работу. На самом деле проверка атрибутов экземпляров как при каждом отдельном доступе к ним (или при создании экземпляров классов) - это не то, что обычно делают большинство программистов. Вы можете попробовать использовать более простые ограничения, такие как ArrayRef вместо ArrayRef[Node], если вы достаточно уверены в достоверности ваших данных. Таким образом, будет проверяться только тип самого значения атрибута, а не значение каждого элемента в этой ссылке на массив.

Но, тем не менее, профилируйте свой код. Не угадай.

7 голосов
/ 12 октября 2010

Я очень подозреваю, что ваша проблема со скоростью не столько в Moose, сколько в распределении памяти и обмене дисками. Даже без выполнения -> meta-> make_immutable, исходя из вашего времени для подмножества 20К, ваш скрипт должен завершиться примерно через 2 часа (((11 * (13_000_000 / 20_000)) / 60) == ~ 119 мин). Делая -> meta-> make_immutable, это сократило бы его до прибл. 65 минут или около того.

Попробуй снова запустить свой большой скрипт и посмотри, что делает твоя память и своп, я подозреваю, что ты ужасно трескаешь диск.

2 голосов
/ 12 октября 2010

Я успешно написал большие приложения для обработки XML с использованием файла XML :: Twig 745 МБ, чтобы запустить его на коробке разумного размера.

Но, как уже упоминали другие пользователи, вам нужно профилировать свой код, чтобы выяснить, что именно является причиной проблемы.

...