这个脚本大约需要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} );
}发布于 2011-05-29 02:51:18
我非常确定Ashley在指出事务和相关的高成本IO时是正确的。
至于XML部分,考虑到输入文档的大小为22MB,您将需要大约200MB的内存,但是处理速度应该相当快,在几秒而不是几分钟的范围内。
看起来效率低下的一件事是您的完整文档扫描XPath表达式。Mediathek/Filme真的可以出现在文档中的任何地方吗?或者它更像是/Archiv/Mediathek/Filme?除非引擎优化这个表达式,否则使用//的效率很低(据我所知,XML::LibXML不会这样做)。
另一件事是,您可以使用$node->getChildElements而不是$node->findnodes("*") (不需要编写./*),但我认为这并不重要。
发布于 2011-05-29 02:39:28
XML::LibXML非常快。如果您对INSERT进行批处理,则SQLite也是如此。SQLite写入活动受到旋转速度的限制,这是其不写入损坏数据的保证的一部分。因此,您正在寻找的速度增益可能是在事务中。在提交之前,批量处理你的许多/所有的INSERT--我认为批量大小的限制因素将是内存。DBI文档描述了如何做到这一点。
同样,这是未经测试的,但即使我错了,学习事务也是很好的。:P
发布于 2011-11-10 06:14:38
你可以尝试几种方法。
XML:: SAX ::ExpatXS非常快,并且使用标准的SAX interfaces.
https://stackoverflow.com/questions/6163156
复制相似问题