MATLAB Lazy Evaluation in Dependent Property

У меня есть класс с несколькими зависимыми свойствами, но я бы очень хотел вычислить только один раз.

Я почти пришел к выводу, что использование ленивой оценки свойства зависимого класса в 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

После наследования от обработать время существенно падает.

10
задан Jay Carlton 10 February 2011 в 19:20
поделиться