怎样提高 matlab 的效率
Post on 03-Jan-2016
146 Views
Preview:
DESCRIPTION
TRANSCRIPT
怎样提高matlab的效率王睿智2011年 4月 15日
作业总结
一维矩阵代替多维矩阵多维矩阵的访问要比一维矩阵要慢,比如 bwlabel里要记录每列的包的编号、开始行号、结束行号、所在列号、所在组号,如果使用五个 1*n的矩阵要比使用一个 5*n的矩阵要快近 4近四倍。
总结一
给数组或矩阵预分配内存 特别是使用大型数组或矩阵时,Matlab进行动态内存分配和取消时,可能会产生内存碎片,这将导致大量闲置内存产生,预分配可通过提前给大型数据结构预约足够空间来避免这个问题。
总结二
用函数代替脚本文件 因为每次调用MATLAB的脚本文件都需要将不必要的中间变量加载到内存中,每执行一次,就加载一次。函数在调用时被编译成了伪代码,只需要加载到内存一次。当多次调用同一个函数时会运行快一些。因此尽量多使用函数文件而少使用脚本文件,也是提高执行效率的一种方法。
总结三
注意Matlab的传参方式Matlab的函数只有传值调用,因此会产生副本,开销很大,比如我第一次用深搜写 bwlabel时,速度慢得像死机。。。所以有时候不得不使用参数的值时,最好设定全局变量。注:如果该参数在函数内部没有被修改,那么在实现时,它实质上用的是传引用调用( call by reference。所以有时候也不用过于担心参数传递的问题。
总结四
循环的优化
Matlab是为矢量和矩阵操作而设计的,因此,可以通过矢量化方法加速M文件的运行。矢量化是指将 for循环和while循环转换为等价的矢量或矩阵操作。
i=0;for n = 0:0.1:1000 i=i+1; y(i)=cos(n);end那么我们可以矢量化为:n= 0:0.1:1000;y=cos(n);
循环矢量化
在必须使用多重循环的情况下,如果两个循环执行的次数不同,则建议在循环的外环执行循环次数少的,内环执行循环次数多的。这样也可以显著提高速度。
多重循环
函数调用
输入:一个 1000000 x 1 的矩阵 u输出:一个 1000000 x 1 的矩阵 v,且 v( i)= u( i)+ 1
问题
matlab 自带的函数,多用 c或 fortran编写,算法考究,效率很高,熟练使用不仅能精简代码,也能保证一定的效率
build-in function
自己定义的函数function y = fm(x) y = x + 1;
在调用时for i = 1 : n
v(i) = fm(u(i)); end
m-file function
就是用@来把一个 function赋到一个变量上,类似于 C/C++的函数指针,或者 C#里面的 delegate的作用
fh = @fm;for i = 1 : nv(i) = fh(u(i));
end
function handle
anonymous function是一种便捷的语法来构造简单的函数,类似于 LISP, Python的 lambda表达式
fa = @(x) x + 1; for i = 1 : nv(i) = fa(u(i));
end
anonymous function
inline function是一种传统的通过表达式字符串构造函数的过程
fi = inline('x + 1', 'x'); for i = 1 : n
v(i) = fi(u(i)); end
inline function
feval的好处在于可以以字符串方式指定名字来调用函数,当然它也可以接受别的参数。
v(i) = feval_r('fm', u(i)); v(i) = feval_r(fh, u(i)); v(i) = feval_r(fa, u(i));
feval
m-function 0.385 sec
function handle 0.615 sec
anonymous function
0.635 sec
inline function 166.00 sec
feval_r('fm', u(i))
8.328 sec
feval_r(fh, u(i)) 0.618 sec
feval_r(fa, u(i)) 0.652 sec
feval_r(@fm, u(i))
2.788 sec
feval_r(@fa, u(i))
34.689 sec
实验结果
m-function慢于直接计算过程 function handle和 anonymous function的开销比使用普通的m-函数要高一些。这可能是由于涉及到句柄解析的时间,而普通的函数在第一次运行前已经在内存中进行预编译。
inline function的运行时间难以接受,这是因为matlab是在每次运行时临时对字符串表达式(进行parse。
分析一
feval_r(@fm, u(i)) > feval_r(fh, u(i))所以预先用一个变量把句柄接下,其效果就是预先完成了句柄解析,而如果直接把@fm写在参数列上,虽然写法简洁一些,但是解析过程是把参数被赋值到所调函数的局部变量时才进行,每调用一次解析一次,造成了巨大的开销。 feval_r('fm', u(i)) > feval_r(fh, u(i)) 因为这涉及到对函数进行搜索的时间
分析二
Matlab支持多种函数调用方式,一般来说,函数调用一般按如下顺序选择:1. build-in function2. m-file function3. function handle4. anonymous function
总结
数据的访问方式
array-index A(i): cell-index: C{i}; struct field: S.fieldname struct field (dynamic): S.('fieldname')
matlab的集中数据访问方式
元胞数组是MATLAB的一种特殊数据类型,可以将元胞数组看做一种无所不包的通用矩阵,或者叫做广义矩阵。组成元胞数组的元素可以是任何一种数据类型的常数或者常量,每一个元素也可以具有不同的尺寸和内存占用空间,每一个元素的内容也可以完全不同,所以元胞数组的元素叫做元胞( cell)。和一般的数值矩阵一样,元胞数组的内存空间也是动态分配的。
cell array
>> a={'matlab',20;ones(2,3),1:10}
a =
'matlab' [ 20] [2x3 double] [1x10 double]
cell array
A(i) for a numeric array
0.0052 sec
C{i} for a cell array
0.2568 sec
struct field 0.0045 sec
struct field (with dynamic name)
1.0394 sec
实验结果
MATLAB对于单个数组元素或者静态的 struct field的访问,可以达到不错的速度。而 cell array的访问则明显缓慢,约每秒 400万次(慢了 50倍)。MATLAB还支持灵活的使用字符串来指定要访问域的语法(动态名字),但是,是以巨大的开销为代价的,比起静态的访问慢了 200倍以上。
分析
OO技术
虽然 object-oriented从软件工程的角度更为优胜,而且 object的使用很多时候很方便,但是MATLAB目前对于 OO的实现效率很低,在效率关键的代码中应该慎用 objects。
谢谢!
top related