XML :: LibXML:Speedquestion

时间:2011-05-28 17:15:29

标签: xml perl performance

此脚本大约需要50分钟,(文件大小:22,3 MiB,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 个答案:

答案 0 :(得分:3)

我非常确定Ashley在指向交易和相关昂贵的IO时是对的。

对于XML部分,如果输入文档大小为22 MB,则需要大约200 MB的内存,但处理速度应相当快,在几秒而不是几分钟的范围内。

看起来效率低下的一件事是你的整个doc-scan XPath表达式。 Mediathek/Filme真的可以出现在文档的任何位置吗?还是像/Archiv/Mediathek/Filme?使用//是低效的,除非引擎优化了这个表达式(据我所知,XML :: LibXML没有这样做)。

另一件事是你可以使用$node->getChildElements而不是$node->findnodes("*")(不需要写./*),但我认为这不重要。

答案 1 :(得分:1)

XML :: LibXML 非常快。 SQLite if 批处理INSERT也是如此。 SQLite写入活动受旋转速度的限制,作为保证不写入损坏数据的一部分。因此,您正在寻找的速度增益可能是在交易中。批量生产的许多/全部INSERT限制因素与批次的大小相比将是我认为在提交之前的RAM。 DBI文档描述了这样做。

同样,这是未经测试的,但即使我错了也要学习交易。 :P

答案 2 :(得分:1)

你可以尝试一些事情。

  1. 鉴于您正在有效地传输XML,您是否可以使用SAX处理器重新实现它? - XML :: SAX :: ExpatXS速度非常快,使用标准的SAX接口。

  2. 您可以考虑为SQL使用批量插入,在单个语句中插入多行,这将限制索引重建的次数。