记住一个XML解析函数会破坏它

问题描述

我是Perl的新手,我需要提高别人编写的应用程序的性能

分析表明该程序在XML::Simple库中花费了大量时间。 基于有关应用程序的使用随时间的变化的知识,我们怀疑它会多次重新解析相同的XML数据。

Memoizing 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。

解决方法

恐怕您的问题中没有足够的信息来完全回答问题所在。 (直到至少有一个MWE才可以)。但是,我想指出您可能需要考虑的两件事。

为了记住一个函数,Memoize使用规范化器来检查参数是否相同。根据{{​​3}},默认情况下只会对参数进行字符串化。这意味着hashref变成其字符串表示形式,这是其在内存中的位置。这将在函数调用之间改变,因此,它将永远无法正确识别出您已经传递了相同的参数。

您可能想提供自己的规范化功能,以解决XML :: Simple所需的特定参数样式。

此外,根据文档中的the docs,如果您的函数返回了引用,则将返回相同的引用。这意味着,如果您在某个时候修改了结构(鉴于给出的信息,我无法知道这种情况是否会发生),那么修改后的结构将在以后返回。