提问人:Emilio M Bumachar 提问时间:8/20/2020 更新时间:8/20/2020 访问量:58
记住 XML 解析函数会破坏它
memoizing an XML parsing function breaks it
问:
我是Perl的新手,我需要提高别人编写的应用程序的性能。
分析表明,该程序在 XML::Simple
库中花费了大量时间。
根据对应用程序的使用如何随时间变化的了解,我们怀疑它正在多次重新分析相同的 XML 数据。
记住 XML 解析函数似乎是一个简单的修复方法。假定它从中获取 XML 数据的文件在程序运行时不会更改,因此我们只缓存每个文件的结果。
这种函数是库的入口点,是 XMLin。
我对软件的唯一更改是添加
use Memoize;
memoize('XMLin');
尝试运行将返回错误:
Not a HASH reference at C:\QuEST\Scripts\RangeAnalyzer/ParseETP.pl line 269.
第 269 行是:
@constantElements = @{$xml->{declarations}->{Package}->{declarations}->{Constant}};
...并定义为:$xml
my $xml = XMLin($Filename, KeyAttr => {ConstValue => '', Operator => '', VariableRef => '', Variable => '', StateMachine => '', State => '', IfBlock => '', WhenBlock => '', SizeParameter => ''}, ForceArray => ['Variable', 'ConstValue', 'DataArrayOp', 'Constant']);
撤消更改可修复错误。
为什么记忆函数会破坏其返回值?如何解决?
我注意到它已被弃用,并且最好用更快的东西替换它,这是要尝试的事情之一。
然而,这个错误打破了我关于记忆应该如何工作的心理模型。XML::Simple
我正在使用 Perl 5.10.0。
答:
2赞
A Gold Man
8/20/2020
#1
恐怕您的问题中没有足够的信息来完全回答出了什么问题。(至少在有 MWE 之前不会)。但是,我想指出您可能需要考虑的两件事。
为了记住一个函数,Memoize 使用归一化器来检查参数是否相同。根据文档,默认情况下,这只会字符串化参数。这意味着 hashref 被转换为其字符串表示形式,即它在内存中的位置。这将在函数的调用之间发生变化,因此它永远不会正确地识别您传递了相同的参数。
您可能希望提供自己的规范化函数来处理 XML::Simple 所需的特定参数样式。
此外,根据文档中的警告部分,如果您的函数返回引用,则返回相同的引用。这意味着,如果您在某个时候修改了结构(鉴于给定的信息,我无法知道是否发生这种情况),那么修改后的结构将在稍后返回。
评论
0赞
ikegami
8/20/2020
如果它们始终传递文件名和相同的选项,则自定义规范化函数可以简单地返回第一个参数(文件名)。如果它们总是传递文件名,但并不总是相同的选项,那么 using 应该可以解决问题。Cpanel::JSON::XS->new->canonical->encode(\@_)
评论
Data::Dumper
$xml
KeyAttr
{...}
memoize