数组/项目中有30,000组数据。 在我的工作服务器上,(A)需要30分钟,(B)需要5秒钟。 在我的家用电脑上,(A)和(B)都需要5秒钟。
为什么(A)在我的工作服务器上这么慢?
===========================================
foreach my $node2 ($node1->findnodes('array/item')){
= APPROACH (A) ============================
$xml_index = $node2->findvalue('index');
$xml_value = $node2->findvalue('value');
= APPROACH (B) ============================
foreach my $node3 ($node2->childNodes){
if($node3->nodeType() == XML_ELEMENT_NODE){
if($node3->getName() eq "index"){
$xml_index=$node3->to_literal();
}
if($node3->getName() eq "value"){
$xml_value=$node3->to_literal();
}
}
}
===========================================
如果你需要看到整件事 -
#! /usr/bin/perl -w
use warnings;
use strict;
use XML::LibXML;
use POSIX qw( strftime );
use File::Basename;
my $parser = XML::LibXML->new();
my $filebase; my $file; my $int; my $boolDone; my $str;
my $line; my $whole; my $name; my $inputfilename;my $inputfolder;my $outputfile; my $doc; my $dt;my $dt1;my $dt2;my $dto_type;
my $xml_index; my $xml_value;
# INPUT
$inputfolder = ".";
opendir (DIR, $inputfolder) or die $!;
while ($inputfilename = readdir(DIR)){
# one loop per file
next if $inputfilename eq '.';
next if $inputfilename eq '..';
if(substr($inputfilename,-4) eq ".dto"){
$doc = $parser->parse_file($inputfolder."/".$inputfilename);
$dto_type = $doc->findvalue('object/class');
if($dto_type eq "sshp.escs.cecs.mips.data.MipsPeerStatusObject_TImpl"){
print "Importing File: ".$inputfilename."\n";
#OUTPUT
$outputfile = &ExtractFilenameNoExt($inputfilename);
$outputfile = $outputfile.".csv";
open(my $fh, '>', $outputfile) or die "Error '$outputfile' $!";
#csv file headers
$line = "index,"."value";
print $fh $line."\n";
$int = 1;
foreach my $node1 ($doc->findnodes('object/field/object/field/object/field/object/field')){
if($node1->findvalue('name') eq "statusData"){
foreach my $node2 ($node1->findnodes('array/item')){
# $xml_index = $node2->findvalue('index');
# $xml_value = $node2->findvalue('value');
foreach my $node3 ($node2->childNodes){
if($node3->nodeType() == XML_ELEMENT_NODE){
if($node3->getName() eq "index"){
$xml_index=$node3->to_literal();
}
if($node3->getName() eq "value"){
$xml_value=$node3->to_literal();
}
}
}
$line = $xml_index.",".$xml_value;
print $fh $line."\n";
$xml_index = "";
$xml_value = "";
if($int %10000 == 0){
print $int."\n";
}
$int++;
}
}
}
close $fh;
}
}
}
my $elapsed_seconds = time - $^T;
print "duration: ".$elapsed_seconds." seconds";
sub ExtractFilenameNoExt(){
my ($file) = @_;
$file = basename($file);
return substr($file,0,(length($file)-length(ExtractExt($file))-1));
}
sub ExtractExt{
my ($file) = @_;
return substr($file, rindex($file, '.') + 1);
}
如果你需要查看xml的样本 -
<?xml version='1.0' encoding='UTF-8'?>
<object>
<field>
<object>
<field>
<object>
<field>
<object>
<field>
<name>statusData</name>
<class>[B</class>
<array>
<class>[B</class>
<size>30152</size>
<item>
<class>java.lang.Byte</class>
<index>0</index>
<value>0</value>
</item>
<item>
<class>java.lang.Byte</class>
<index>1</index>
<value>0</value>
</item>
<item>
<class>java.lang.Byte</class>
<index>30150</index>
<value>-63</value>
</item>
<item>
<class>java.lang.Byte</class>
<index>30151</index>
<value>-24</value>
</item>
</array>
</field>
</object>
</field>
</object>
</field>
</object>
</field>
</object>
答案 0 :(得分:2)
我会尝试更像:
use XML::Rules;
my @rules = (
item => [
'array' => sub {
my $item = $_[1];
print "index: $item->{index} value: $item->{value}\n";
},
],
'index,value' => 'content',
_default => undef,
);
my $xr = XML::Rules->new(
rules => \@rules,
);
$xr->parse($xml);
# or
$xr->parse_file($xml_file);
答案 1 :(得分:1)
在你的方法A中,我认为findvalue方法创建了一个内部读取所有内容的循环。 我要做的是尝试编写类似于方法B
的东西