Transcript
Page 1: 怎样提高 matlab 的效率

怎样提高matlab的效率王睿智2011年 4月 15日

Page 2: 怎样提高 matlab 的效率

作业总结

Page 3: 怎样提高 matlab 的效率

一维矩阵代替多维矩阵多维矩阵的访问要比一维矩阵要慢,比如 bwlabel里要记录每列的包的编号、开始行号、结束行号、所在列号、所在组号,如果使用五个 1*n的矩阵要比使用一个 5*n的矩阵要快近 4近四倍。

总结一

Page 4: 怎样提高 matlab 的效率

给数组或矩阵预分配内存 特别是使用大型数组或矩阵时,Matlab进行动态内存分配和取消时,可能会产生内存碎片,这将导致大量闲置内存产生,预分配可通过提前给大型数据结构预约足够空间来避免这个问题。 

总结二

Page 5: 怎样提高 matlab 的效率

用函数代替脚本文件  因为每次调用MATLAB的脚本文件都需要将不必要的中间变量加载到内存中,每执行一次,就加载一次。函数在调用时被编译成了伪代码,只需要加载到内存一次。当多次调用同一个函数时会运行快一些。因此尽量多使用函数文件而少使用脚本文件,也是提高执行效率的一种方法。 

总结三

Page 6: 怎样提高 matlab 的效率

注意Matlab的传参方式Matlab的函数只有传值调用,因此会产生副本,开销很大,比如我第一次用深搜写 bwlabel时,速度慢得像死机。。。所以有时候不得不使用参数的值时,最好设定全局变量。注:如果该参数在函数内部没有被修改,那么在实现时,它实质上用的是传引用调用( call by reference。所以有时候也不用过于担心参数传递的问题。

总结四

Page 7: 怎样提高 matlab 的效率

循环的优化

Page 8: 怎样提高 matlab 的效率

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);

循环矢量化

Page 9: 怎样提高 matlab 的效率

在必须使用多重循环的情况下,如果两个循环执行的次数不同,则建议在循环的外环执行循环次数少的,内环执行循环次数多的。这样也可以显著提高速度。

多重循环

Page 10: 怎样提高 matlab 的效率

函数调用

Page 11: 怎样提高 matlab 的效率

输入:一个  1000000 x 1 的矩阵 u输出:一个  1000000 x 1 的矩阵 v,且 v( i)= u( i)+ 1

问题

Page 12: 怎样提高 matlab 的效率

matlab 自带的函数,多用 c或 fortran编写,算法考究,效率很高,熟练使用不仅能精简代码,也能保证一定的效率

build-in function

Page 13: 怎样提高 matlab 的效率

自己定义的函数function y = fm(x) y = x + 1;

在调用时for i = 1 : n

v(i) = fm(u(i)); end

m-file function

Page 14: 怎样提高 matlab 的效率

就是用@来把一个 function赋到一个变量上,类似于 C/C++的函数指针,或者 C#里面的 delegate的作用

fh = @fm;for i = 1 : nv(i) = fh(u(i));

end

function handle

Page 15: 怎样提高 matlab 的效率

anonymous function是一种便捷的语法来构造简单的函数,类似于 LISP, Python的 lambda表达式

fa = @(x) x + 1; for i = 1 : nv(i) = fa(u(i));

end

anonymous function

Page 16: 怎样提高 matlab 的效率

inline function是一种传统的通过表达式字符串构造函数的过程

fi = inline('x + 1', 'x'); for i = 1 : n

v(i) = fi(u(i)); end

inline function

Page 17: 怎样提高 matlab 的效率

feval的好处在于可以以字符串方式指定名字来调用函数,当然它也可以接受别的参数。

v(i) = feval_r('fm', u(i)); v(i) = feval_r(fh, u(i)); v(i) = feval_r(fa, u(i));

feval

Page 18: 怎样提高 matlab 的效率

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

实验结果

Page 19: 怎样提高 matlab 的效率

m-function慢于直接计算过程 function handle和 anonymous function的开销比使用普通的m-函数要高一些。这可能是由于涉及到句柄解析的时间,而普通的函数在第一次运行前已经在内存中进行预编译。 

inline function的运行时间难以接受,这是因为matlab是在每次运行时临时对字符串表达式(进行parse。 

分析一

Page 20: 怎样提高 matlab 的效率

feval_r(@fm, u(i)) > feval_r(fh, u(i))所以预先用一个变量把句柄接下,其效果就是预先完成了句柄解析,而如果直接把@fm写在参数列上,虽然写法简洁一些,但是解析过程是把参数被赋值到所调函数的局部变量时才进行,每调用一次解析一次,造成了巨大的开销。 feval_r('fm', u(i)) > feval_r(fh, u(i)) 因为这涉及到对函数进行搜索的时间

分析二

Page 21: 怎样提高 matlab 的效率

Matlab支持多种函数调用方式,一般来说,函数调用一般按如下顺序选择:1. build-in function2. m-file function3. function handle4. anonymous function

总结

Page 22: 怎样提高 matlab 的效率

数据的访问方式

Page 23: 怎样提高 matlab 的效率

array-index  A(i):   cell-index:  C{i};   struct field:  S.fieldname  struct field (dynamic):  S.('fieldname') 

matlab的集中数据访问方式

Page 24: 怎样提高 matlab 的效率

元胞数组是MATLAB的一种特殊数据类型,可以将元胞数组看做一种无所不包的通用矩阵,或者叫做广义矩阵。组成元胞数组的元素可以是任何一种数据类型的常数或者常量,每一个元素也可以具有不同的尺寸和内存占用空间,每一个元素的内容也可以完全不同,所以元胞数组的元素叫做元胞( cell)。和一般的数值矩阵一样,元胞数组的内存空间也是动态分配的。

cell array

Page 25: 怎样提高 matlab 的效率

>> a={'matlab',20;ones(2,3),1:10}

a =

    'matlab'        [         20]    [2x3 double]    [1x10 double]

cell array

Page 26: 怎样提高 matlab 的效率

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

实验结果

Page 27: 怎样提高 matlab 的效率

MATLAB对于单个数组元素或者静态的 struct field的访问,可以达到不错的速度。而 cell array的访问则明显缓慢,约每秒 400万次(慢了 50倍)。MATLAB还支持灵活的使用字符串来指定要访问域的语法(动态名字),但是,是以巨大的开销为代价的,比起静态的访问慢了 200倍以上。

分析

Page 28: 怎样提高 matlab 的效率

OO技术

Page 29: 怎样提高 matlab 的效率

虽然 object-oriented从软件工程的角度更为优胜,而且 object的使用很多时候很方便,但是MATLAB目前对于 OO的实现效率很低,在效率关键的代码中应该慎用 objects。

Page 30: 怎样提高 matlab 的效率

谢谢!