XML :: LibXML: Speedquestion - PullRequest
       1

XML :: LibXML: Speedquestion

1 голос
/ 28 мая 2011

Этот сценарий занимает около 50 минут (размер файла: 22,3 МБ, cpu: atom).
Это нормально (50 минут)?
Могу ли я настроить сценарий, чтобы сделать его быстрее?

#!/usr/local/bin/perl
use XML::LibXML;
use DBI;

my $dbh = DBI->connect( "DBI:SQLite:dbname=$db", undef, undef, $options );
my $sth = $dbh->prepare( "INSERT INTO $table ( id, titel, ... ) VALUES ( ?, ?, ... )" );

my $parser = XML::LibXML->new();
my $doc = $parser->load_xml( location => $file );
my @nodes = $doc->findnodes( '//Mediathek/Filme' );

my @keys = qw( Id Titel ... );

for my $node ( @nodes ) {
    my @nodes = $node->findnodes( './*' );
    my %hash;
    @hash{@keys} = ();
    for my $node ( @nodes ) {
        $hash{$node->nodeName} = $node->textContent;
    }
    $sth->execute( @hash{@keys} );
}

Ответы [ 3 ]

3 голосов
/ 28 мая 2011

Я почти уверен, что Эшли права, когда указывает на транзакции и связанные с ними дорогостоящие операции ввода-вывода.

Что касается части XML, то с учетом размера входного документа 22 МБ вам потребуется около 200 МБ памяти, но обработка должна быть достаточно быстрой, в диапазоне секунд, а не минут.

Одна вещь, которая выглядит неэффективной, это выражение XPath для всего сканирования документов. Может ли Mediathek/Filme действительно появляться где-нибудь в документе? Или это скорее что-то вроде /Archiv/Mediathek/Filme? Использование // неэффективно, если механизм не оптимизирует это выражение (насколько я знаю, XML :: LibXML не делает).

Другое дело, что вы могли бы использовать $node->getChildElements вместо $node->findnodes("*") (не нужно писать ./*), но я не думаю, что это будет иметь большое значение.

1 голос
/ 10 ноября 2011

Вы можете попробовать несколько вещей.

  1. Учитывая, что вы эффективно транслируете свой XML, не могли бы вы повторно реализовать его с помощью SAX-процессора?- XML ​​:: SAX :: ExpatXS невероятно быстр и использует стандартные интерфейсы SAX.

  2. Вы можете использовать массовую вставку для SQL, вставляя несколько строк в один оператор, этоограничит количество перестроений индекса.

1 голос
/ 28 мая 2011

XML :: LibXML очень быстро.И так же SQLite , если вы пакетируете INSERT s.Операция записи SQLite ограничена скоростью вращения как часть гарантии того, что данные не будут записаны.Таким образом, увеличение скорости, которое вы ищете, вероятно, в транзакции.Пакетируйте многие / все ваши INSERT с - я думаю, что ограничивающим фактором для размера пакетов будет ОЗУ - перед фиксацией.Документы DBI описывают это.

Опять же, это не проверено, но хорошо изучать транзакции, даже если я ошибаюсь.: P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...