从属属性中的 MATLAB 惰性求值

Posted

技术标签:

【中文标题】从属属性中的 MATLAB 惰性求值【英文标题】:MATLAB Lazy Evaluation in Dependent Property 【发布时间】:2011-06-25 01:59:56 【问题描述】:

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

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

我认为困难在于对属性访问器的限制,即它们不理会其他不相关的属性。换句话说,get.property(self) 方法不能改变 self 对象的状态。有趣的是,这在我目前的课程中默默地失败了。 (即get.方法中既没有设置更新标志也没有设置缓存的计算结果,所以每次都运行昂贵的计算。

我怀疑将惰性属性从公共依赖属性更改为具有公共 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

运行它
close all; clear classes; clc

t = LazyTest(3)
t.factorial

for num = 1:10
  tic
  t.factoriand = num
  t.factorial
  toc
end

handle继承后,时间大幅下降。

【问题讨论】:

【参考方案1】:

我假设您使用的是值类。使用通过引用传递的handle class (classdef myClass < handle),您可以轻松地从 get 方法中修改类。例如,我使用您建议的方式从文件(如果尚未加载)或私有隐藏属性中加载数据。

请注意,以您提议的方式使用 lazy 依赖属性在某种程度上违背了使用依赖属性的目的,即保证您的数据始终与它所派生的属性的状态保持同步。每次更改其他属性时,您的惰性属性都会过时。

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

【讨论】:

我也喜欢在我关心的对象上使用 isempty 与额外的私有属性相比减少了混乱。谢谢。 1.您不能在不做一些假设的情况下根据值将显式标志替换为隐式标志(此处,空值在此处无效)。 2. 让 set 方法更新“依赖”属性可能并不总是合适的,尤其是。如果后者的计算成本很高并且取决于两个或多个其他属性。因此,在一般情况下,我仍然会使用额外的标志。

以上是关于从属属性中的 MATLAB 惰性求值的主要内容,如果未能解决你的问题,请参考以下文章

Python中的惰性求值

Python:any() / all() 中的惰性函数求值

C#函数式编程中的惰性求值详解

理解 pyspark 中的惰性求值行为

奇怪的 jags.parallel 错误/避免函数调用中的惰性求值

在不知道属性类型的情况下从属性和列表值中获取属性值