34.3.2索引赋值优化

Octave无处不在的延迟复制传递值语义暗示了用户定义的性能问题subs方法。想象一下以下调用subs

ss=子结构体(“()”,{1});x=subsasgn(x,ss,1);

其中对应的方法如下所示:

函数x=subsasgn(x,ss,val)。。。x.myfield(ss.subs{1})=val;结束函数

问题是,在进入subs方法x仍然从调用方的作用域中引用,这意味着该方法将首先需要取消共享(复制)xx.myfield在执行赋值之前。完成调用后,除非出现错误,否则会立即将结果赋值给x在调用方的作用域中,以便的previousvaluex.myfield被遗忘了。因此,Octave语言意味着N个元素的副本(N是的大小x.myfield),其中仅修改一个元素实际上就足够了。换言之,恒定时间操作降级为线性时间操作。对于本质上存储大型数组的用户类来说,这可能是一个真正的问题。

为了部分解决这个问题,Octave使用了一个特殊的优化,用于用户定义subs编码为m文件的方法。当方法从于内置赋值语法(而不是直接赋值语法)而被缩放时subs如上所示的呼叫)。,x(1)=1, 以及ifthesubs方法是用相同的输入和输出参数语句的,如上例所示,那么Octave将忽略的副本x在调用者的范围内;因此,对所做的任何更改x在方法执行期间,也将直接影响调用方的副本。例如,这允许定义一个多项式类,其中修改单个元素需要恒定的时间。

了解这种优化带来的影响是很重要的。从于没有额外的副本x将存在于调用者的作用域中,它是唯一地被叫方不离开的责任x如果在执行过程中发生错误,则处于无效状态。此外,如果方法部分更改x然后出错,更改影响x在调用者的作用域中。删除或完全替换xinsidesubsasgn不会做任何事情,但是,只有索引赋值才重要。

从于这种优化可能会改变代码的工作方式(尤其是在编写错误的情况下)优化subsasgn_calls提供用于控制它。此函数在默认情况下处于启用状态。另一种避免优化的方法是语句具有不同输出和输入参数的subsasgn方法,如下所示:

函数y=subsasgn(x,ss,val)。。。结束函数

版权所有 © 2024 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号