gpt4 book ai didi

xml - 使用 XML::Twig 处理巨大文件 (>10 GB) 的性能问题

转载 作者:行者123 更新时间:2023-12-04 05:08:44 25 4
gpt4 key购买 nike

我必须处理一个巨大的 XML 文件(> 10 GB)才能将其转换为 CSV。我正在使用 XML::Twig .

该文件包含大约 260 万客户的数据,每个客户将有大约 100 到 150 个字段(取决于客户资料)。

我将一个订阅者的所有值存储在哈希中 %customer ,处理完成后,我将哈希值输出到 CSV 格式的文本文件中。

问题是性能。处理它大约需要 6 到 8 个小时。怎样才能减少?

my $t = XML::Twig->new(
twig_handlers => {
'objects/simple' => \&simpleProcess ,
'objects/detailed' => \&detailedProcess ,
},
twig_roots => { objects => 1}
);

sub simpleProcess {
my ($t, $simple) = @_;

%customer= (); #reset the hash
$customer{id} = $simple->first_child_text('id');
$customer{Key} = $simple->first_child_text('Key');
}

详细标签包括多个字段,包括嵌套字段。所以我每次都会调用一个函数来收集不同类型的字段。
sub detailedProcess {
my ($t, $detailed1) = @_;

$detailed = $detailed1;
if ($detailed->has_children('profile11')){ &profile11();}
if ($detailed->has_children('profile12')){ &profile12();}
if ($detailed->has_children('profile13')){ &profile13();}
}
sub profile11 {
foreach $comcb ($detailed->children('profile11')) {
$customer{COMCBcontrol} = $comcb->first_child_text('ValueID');
}

其他函数 *(value2, value3) 也是如此。我没有提到保持简单的其他功能。
<objecProfile>
<simple>
<id>12345</id>
<Key>N894FE</Key>
</simple>
<detailed>
<ntype>single</ntype>
<SubscriberType>genericSubscriber</SubscriberType>
<odbssm>0</odbssm>
<osb1>true</osb1>
<natcrw>true</natcrw>
<sr>2</sr>
<Profile11>
<ValueID>098765</ValueID>
</Profile11>
<Profile21>
<ValueID>098765</ValueID>
</Profile21>
<Profile22>
<ValueID>098765</ValueID>
</Profile22>
<Profile61>
<ValueID>098765</ValueID>
</Profile61>
</detailed>
</objectProfile>

现在的问题是:我使用 foreach对于每个 child ,即使几乎每次 child 实例在整个客户文件中只出现一次。它会导致延迟,还是有任何其他建议可以提高性能?线程等? (我用谷歌搜索,发现线程并没有多大帮助。)

最佳答案

我建议使用 XML::LibXML::Reader .它非常高效,因为它不会在内存中构建 XML 树,除非您要求它,并且它基于优秀的 LibXML 库。

您将不得不习惯与 XML::Twig 不同的 API。 ,但 IMO 仍然相当简单。

这段代码与您自己的代码完全一样,我的计时表明,像您展示的那样的 1000 万条记录将在 30 分钟内得到处理。

它的工作原理是重复扫描下一个 <object>元素(我不确定这是否应该是 <objecProfile>,因为您的问题不一致),将节点及其后代复制到 XML::LibXML::Element对象 $copy以便可以访问子树,并将所需的信息拉出到%customer .

use strict;
use warnings;

use XML::LibXML::Reader;

my $filename = 'objects.xml';

my $reader = XML::LibXML::Reader->new(location => $filename)
or die qq(cannot read "$filename": $!);

while ($reader->nextElement('object')) {

my %customer;

my $copy = $reader->copyCurrentNode(1);

my ($simple) = $copy->findnodes('simple');
$customer{id} = $simple->findvalue('id');
$customer{Key} = $simple->findvalue('Key');

my ($detailed) = $copy->findnodes('detailed');
$customer{COMCBcontrol} = $detailed->findvalue('(Profile11 | Profile12 | Profile13)/ValueID');

# Do something with %customer
}

关于xml - 使用 XML::Twig 处理巨大文件 (>10 GB) 的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15171731/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com