Matlab 程序效率低下,其中一个原因就是它的参数无法引用,每次都是传值。这不但导致效率问题,要实现某些功能,也需要一些特殊的手段。比如最简单的,如果交换两个变量的值,也就是在 C/C++里的函数 void swap(int& a, int& b),在 C/C++里实现很容易,但在 Matlab 里,你会吗?
下面这个解决方法很巧妙,因为它的实现很有参考价值(来源,可以下载.m 版本),附在下面欣赏一下。
function swap(A,B)
% SWAP - swap contents of two variables
% SWAP(A,B) puts the contents of variable A into variable B and vice versa.
% You can use either function syntax 'swap(A,B)' or command syntax 'swap A B'.
%
% Example:
% A = 1:4 ; B = 'Hello' ;
% swap(A,B) ;
% A % -> Hello
% B % -> 1 2 3 4
%
% SWAP(A,B) is a convenient easy short-cut for other (series of)
% commands that have the same effect, e.g.,
% temp=A ; A=B ; B=temp ; clear temp ;
% [B,A] = deal(A,B) ;
% The advantage over these two methods is that using SWAP one does not
% have to declare intermediate variables or worry about output.
%
% See also DEAL
% Tested in Matlab R13
% version 1.1 (sep 2006)
% (c) Jos van der Geest
% email: jos@jasen.nl
% 1.1 Use <deal> to swap (insight from Urs Schwarz)
% Added command syntax functionality (suggested by Duane Hanselman)
% Modified help section
error(nargchk(2,2,nargin)) ;
if ischar(A) && ischar(B),
% command syntax: SWAP VAR1 VAR2
evalstr = sprintf('[%s,%s] = deal(%s,%s) ;',B,A,A,B) ;
elseif ~isempty(inputname(1)) && ~isempty(inputname(2)),
% function syntax: SWAP(VAR1,VAR2)
evalstr = sprintf('[%s,%s] = deal(%s,%s) ;',inputname(2),inputname(1),inputname(1),inputname(2)) ;
else
% No valid command syntax, force error
evalstr = '[:)' ;
end
evalin('caller',evalstr,'error(''Requires two (string names of) existing variables'')') ;
另外附 Matlab 参数传递的方式(来源):
Matlab 使用的是一种叫作"copy-on-write"的矩阵拷贝构造函数,假如你定义了函数
function myfun(A,B) do something
并在主程序中调用了
myfun(Amat,Bmat)
,此时程序并不是把 Amat/Bmat 的内容全部复制给 A 和 B ,而是新建两个局部变量 A 和 B ,这两个变量的数据部分通过两个指针分别指向 Amat 和 Bmat 数据段进行共享数据,并把 Amat/Bmat 中的一个叫作 refcnt(reference count)的变量加一。这样避免了拷贝大量数据的开销。在 myfun 中,如果你只读取 A 中的数据,此时,使用 A 完全等价于使用 Amat 中的数据, 但如果你需要修改 A 中的数据,此时 Matlab 先检查 A(Amat)的 refcnt ,如果这个数大于 1,则说明除了 A,还有其他矩阵也同时共享这个数据,为了保证这次修改仅对于 A 有效,这时候 Matlab 才会在内存中复制原来 Amat 的数据内容给 A ,然后修改 A 中的数据。此时 A 已与 Amat 分离。
大多数 C++矩阵类都是通过 refcnt 的机制来进行复制的。
如果有大量参数传递,可以考虑写 c mex/fortran mex ,也可以使用 global ,还可以用
evalin(WS,...)
。
Q. E. D.