依赖属性中的MATLAB惰性评估

Jay*_*ton 10 oop matlab properties accessor lazy-evaluation

我有一个具有一些依赖属性的类,但我真的只想计算一次.

我刚刚得出结论,在MATLAB中对依赖类属性使用惰性求值要么是不可能的,要么是个坏主意.最初的计划是为每个需要更新的(公共)属性创建一个私有逻辑标志,并让构造函数将其设置为true.然后,当调用属性访问器时,它将检查该标志并计算该值并仅在需要时将其存储(在另一个私有属性中).如果该标志为false,则只返回缓存值的副本.

我认为困难在于对属性访问者的限制,即他们只留下其他不相关的属性.换句话说,get.property(self)方法不能更改self对象的状态.有趣的是,这在我当前的课堂上无声地失败了.(即,更新标志和缓存计算结果都没有在get.方法中设置,因此每次都运行昂贵的计算).

我怀疑是将lazy属性从公共依赖属性更改为具有公共GetAccess但私有SetAccess的方法将起作用.但是,我不喜欢以这种方式欺骗财产惯例.我希望只有一个"懒惰"的属性可以为我做这一切.

我错过了一些明显的东西吗 是否禁止在MATLAB中依赖类属性的访问器方法来更改类实例的状态?如果是这样,那么定义具有私有副作用的访问者的数量是获得我想要的行为的最不邪恶的方式吗?

编辑:这是一个测试类......

classdef LazyTest
  properties(Access = public)
    % num to take factorial of
    factoriand
  end

  properties(Access = public, Dependent)
    factorial
  end

  properties(Access = private)
    % logical flag
    do_update_factorial
    % old result
    cached_factorial
  end

  methods
    function self = LazyTest(factoriand)
      self.factoriand = factoriand;
      self.do_update_factorial = true;
    end
  end

  methods
    function result = get.factorial(self)
      if self.do_update_factorial
        self.cached_factorial = factorial(self.factoriand);
        % pretend this is expensive
        pause(0.5)
        self.do_update_factorial = false
      end
      result = self.cached_factorial;
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

运行它

close all; clear classes; clc

t = LazyTest(3)
t.factorial

for num = 1:10
  tic
  t.factoriand = num
  t.factorial
  toc
end
Run Code Online (Sandbox Code Playgroud)

继承之后handle,时间大幅下降.

Jon*_*nas 11

我假设你正在使用价值类.使用通过引用传递的句柄类(classdef myClass < handle),您可以在get-method中轻松修改类.例如,我使用您建议的内容来从文件(如果尚未加载)或从私有​​隐藏属性加载数据.

请注意,使用lazy依赖属性时,您提出的方式有点违背了使用依赖属性的目的,即保证您的数据始终与其派生的属性的状态保持同步.每次更改其他属性时,您的懒惰属性都会过时.

您可以(应该)将set-method添加到将private属性设置为空的所有其他属性(isempty(obj.myPrivateProperty)是您需要知道是否必须计算的"逻辑标志").但是,如果你这样做,为什么不让set-methods调用一些更新方法来立即更新/重新计算所有"依赖"属性?

  • 1.您无法在不做出某些假设的情况下使用基于值的隐式标记替换显式标志(此处,空值在此处无效).2.设置方法更新"依赖"属性可能并不总是合适的,尤其是 如果后者计算成本高,并且依赖于两个或更多其他属性.因此,在一般情况下,我仍然会使用额外的标志. (2认同)