在MATLAB

时间:2016-05-11 08:32:35

标签: matlab oop memory-management

在我的代码中,我有很多地方可以调用

形式的函数
X = f(X)

和X可以是一个相当大的矩阵。在我的特殊情况下,我主要打电话给

X = feval(somefunc, X)

X = obj.myfunc(X)

如果每次调用函数时都会为X分配新的空间,那将是不好的.MATLAB是否足够智能来处理这样的函数调用?有办法告诉吗?

这个问题的答案对于设计决策非常有帮助。我喜欢以面向对象的方式编程,如果MATLAB对此不够智能,那么在课堂上为X添加另一个成员可能会有所收获,尽管我宁愿不这样做。

1 个答案:

答案 0 :(得分:6)

在MATLAB中调用函数时是否复制输入参数取决于函数内部发生的事情。

MATLAB使用称为copy-on-write的系统。这意味着如果将大变量作为输入传递给函数,只要不修改该函数中的变量,该变量就不会被复制到函数的工作空间中,而是函数将从中读取数据。它是记忆中的当前位置。

function Y = func(X)
    Y = X + 1;
end

如果 修改函数中的变量,则输入变量的副本将被放置到函数的本地工作空间中。

function X = func(X)
    X = X + 1;
end

有关Loren's Mathworks blog的更多信息。

确定是否创建数据副本的简单方法是使用未记录的format debug模式,该模式将显示给定变量的数据存储在内存中的位置。

format debug

%// Create a variable a and show where debug info
a = [1,2]

%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20
%// pi = 0
%//      1     2

%// Assign b = a but don't modify
b = a

%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20  <= POINTER TO DATA REMAINED UNCHANGED
%// pi = 0
%//      1     2

%// Modify (Will create a new copy)
b = b + 1

%// Structure address = 141f55b40
%// m = 1
%// n = 2
%// pr = 7f953bcf1a20   <= POINTER TO DATA CHANGED (COPY)
%// pi = 0
%//      2     3

如果您愿意,可以使用我创建的这个小匿名函数来检查任何特定变量的内存位置。

memoryLocation = @(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')

a = [1,2];
memoryLocation(a)
%// 7f9540b85e20

b = a;
memoryLocation(b)
%// 7f9540b85e20

b = b + 1;
memoryLocation(b)
%// 7f953bcf1a20

作为一个侧面说明,我建议不要在整个代码中使用feval,而是直接使用函数名称。