2014-01-26 4 views
1

В методе Matlab каждый класс кажется обычным методом, первым аргументом которого является сам объект.Сколько накладных расходов создается парадигмой oop в matlab

Такая парадигма вполне приемлема для других языков oop, таких как python, поскольку классы передаются по ссылке. С другой стороны, Matlab по умолчанию передает объекты по значению (кроме классов дескриптора).

Из всех этих я делаю вывод, что использование даже самой простой функции setter (или любого другого метода класса) приведет к копированию всего объекта.

Например, вот сигнатура некоторого метода класса в MATLAB:

classdef foo 
    methods 
    function obj = set.myParam(obj,value); 
    function myfun(obj, value); 
    end 
end 

В этом случае, будет MatLab скопировать весь FooObj = Foo(), когда я называю fooObj.myfun (5) (или просто myfun (fooObj, 5))?

Разве это не невероятно большие накладные расходы? Копирование всего объекта для каждого метода класса (и сеттера) кажется мне невероятно неэффективным.

Пропустить что-нибудь? Во всяком случае, чтобы избежать такой ситуации в Matlab при использовании техники oop?

Должен ли я использовать классы ручек для предотвращения таких накладных расходов на производительность?

ответ

3

Если вы хотите, чтобы ваш класс имел ссылочную семантику, тогда да, вам нужно использовать класс handle, а не класс значений.

Но обратите внимание, что, хотя по умолчанию MATLAB передает аргументы по значению, он также использует ленивое копирование или копию на записи, поэтому копия только сделанное из входных аргументов, если входные аргументы должны быть изменены. Кроме того, если входной аргумент представляет собой структуру или объект, копия производится только из частей (полей, свойств), которые необходимо изменить.

А также дополнительно, MATLAB имеет в месте оптимизации таким образом, что если выходной аргумент такой же, как входной аргумент, и операции на входной аргумент может быть сделано на месте, то копия не требуется.

Так, к примеру, рассмотрим следующую функцию:

function y = timestwo(x) 
y = 2*x; 

Если вы начинаете с переменной a в базовом рабочем пространстве (скажем, это очень большой массив удваивается) и вызвать b = timestwo(a), копия не является из a, так как x не изменяется во время работы. Использование памяти увеличивается только при назначении выходного аргумента y.

Но рассмотрим эту функцию:

function y = timestwoconj(x) 
x = x'; 
y = 2*x; 

теперь увеличивается использование памяти во время выполнения функции, так как копия сделана из x, как он изменяется. Такое же пространство выделяется, когда вычисляется y, а затем, когда функция выходит из временной копии x, очищается.

Это иллюстрирует копию поведения записи.

Рассмотрит также следующую функцию:

function x = timestwo(x) 
x = 2*x; 

Здесь выходной аргумент таким же, как входной аргумент, и все операции могут быть сделаны на месте. Если вы звоните a = timestwo(a), копия вообще не производится, а использование памяти не увеличивается. Это иллюстрирует оптимизированное поведение на месте.

Попробуйте реализовать некоторые функции, аналогичные приведенным выше, применив их к большому массиву, а затем пропустив их в отладчике по очереди при просмотре использования памяти в диспетчере задач - вы получите эту идею.

При реализации классов значений в MATLAB вы обычно используете синтаксис для своих методов, таких как function obj = myfun(obj, value), а не function myfun(obj, value). Методы имеют такой же способ работы, как описано выше, поэтому ваш объект будет скопирован только в том случае, если вы изменяете его во время метода.

Когда вы работаете с классами значений, это то, что вы хотите сделать - если вам нужна эталонная семантика, используйте класс дескриптора.

Надеюсь, что это поможет!

+0

это документировано? – Lee

+1

@Lee Биты о классах дескриптора и значения явно документированы. Биты о методах копирования и записи на месте оптимизируются как документально, но не очень четко или явно (например, я не думаю, что в документе есть отдельная страница, посвященная любой теме). –

Смежные вопросы