在我的代码中,我有很多地方可以调用
形式的函数X = f(X)
和X可以是一个相当大的矩阵。在我的特殊情况下,我主要打电话给
X = feval(somefunc, X)
或
X = obj.myfunc(X)
如果每次调用函数时都会为X分配新的空间,那将是不好的.MATLAB是否足够智能来处理这样的函数调用?有办法告诉吗?
这个问题的答案对于设计决策非常有帮助。我喜欢以面向对象的方式编程,如果MATLAB对此不够智能,那么在课堂上为X添加另一个成员可能会有所收获,尽管我宁愿不这样做。
答案 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
,而是直接使用函数名称。