提高MATLAB程序效率的几点原则,这些都是俺在这两年中参加四次数模编写大量m程序总结的经验,加之网上很多英雄也是所见略同。
1.“计算向量、矩阵化,尽量减少for循环。”因为MATLAB本来就是矩阵实验室的意思,他提供了极其强大而灵活的矩阵运算能力,你就没必要自己再用自己编写的for循环去实现矩阵运算的功能了。另外由于matlab是一种解释性语言,所以最忌讳直接使用循环语句。但在有些情况下,使用for循环可以提高程序的易读性,在效率提高不是很明显的情况下可以选择使用for循环。口说无凭,下面是利用tic与toc命令计算运算所用时间的方法,测试两种编程的效率。需要说明的是没有办法精确计算程序执行时间,matlab帮助这样写到“Keep in mind that tic and toc measure overall elapsed time. Make sure that no other applications are running in the background on your system that could affect the timi ng of your MATLAB programs.”意思是说在程序执行的背后很可能有其他程序在执行,这里涉及到程序进程的的问题,m程序执行的过程中很可能有其他进程中断m程序来利用cup,所以计算出来的时间就不仅是m程序的了,在这种情况下我把那些寄点去掉,进行多次计算求他的平均时间。n = 100;
A(1:1000,1:1000) = 13;
C(1:1000,1) = 15;
D(1:1000,1) = 0;
for k = 1:n
D(:) = 0;
tic
for i = 1:1000
for j = 1:1000
D(i) = D(i) + A(i,j)*C(j);
end
endmatlab难还是c语言难
t1(k) = toc;
%------------------
D(:) = 0;
tic
D = A*C;
t2(k) = toc;
end
u = t1./t2;
u(u<0) = [];
plot(u)
p = mean(u)  t1、t2分别代表用for循环编程和矩阵化编程计算矩阵乘向量所用时间,u代表时间的比值。u(u<0) = [];是认为t1不可能小于t2,所以去掉不可能出现的情况。然后画出图形计算平均值。经多次试验结果大致相同,其中一次结果如下: p =    9.6196 ------------t1时间是t2的十倍左右。
2.“循环内大数组预先定义--预先分配空间”这一点原则是极其重要的,以至于在编写m程序时编辑器会给出提示“'ver' might be growing inside a loop.Consider prealloacting for speed.” clear
n = 50;
m = 1000;
for k = 1:n
A = [];
tic
A(1:m,1:m) = 3;
for i = 1:m
A(i,i) = i;
end
t1(k) = toc;
%------------
A = [];
tic
for j = 1:m
A(j,j) = j;
end
t2(k) = toc;
end
t2(t1>10^9) = [];
t1(t1>10^9) = [];
plot([t1;t2]')t1、t2分别表示预先分配空间和循环中分配空间的时间,下图上面一条t2、下面t1
3.“尽可能利用matlab内部提供的函数”因为matlab内部提供的函数绝对是各种问题的最优算法,那写程序都是他们大师级人物写出来的,程序应该说相当高效,有现成的为什么不用那!这个原则就不用实际的程序测试了。
关于MATLAB程序提速的问题,可以参考网上很多智者的文章,都比较经典。也可以看看我的上一篇文章,和网上大部分帖子有点不同,我是以实际的测试程序作为依据对如何提高MATLAB程序速度进行介绍的。这里我再补充几点大家需要注意的。下面是我在国内一个比较出名的论坛看到的关于m程序提速的帖子,开始还真以为他们谈论的都应该遵循。(尽信书不如无书)帖子的一部分这样说道:“当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
A = int8(zeros(100));
换成:
A = repmat(int8(0), 100, 100);”
凡事不能只凭自己的感觉,没有一点实际的例子,对于权威我们还要有挑战精神那,就不用说现在还不是经典的观点了。下面是我写的测试程序,我本来是想得到这位网友大哥的结果,但是实事不是我们想象的那么简单。
n = 100;
m = 1000;
for k=1:n
tic
A = int8(ones(m));
t1(k) = toc;
tic
B = repmat(int8(1),m,m);
t2(k) = toc;
end
plot(1:n,t1,'r',1:n,t2)
isequal(A,B)可以看出下面的红线是t1,而且最后的一句返回1,说明两种形式返回的值完全一样。
由此我想说的是,不管是在我们做论文,还是写博客的时候,别直接从网上或者别人文章那儿点知识定理之类的补充自己那苍白无力的文章。最好是自己动手编一下,“实践是检验真理的唯一标准”。经过这一测试,我感觉有必要,也有责任对这个论坛上的一大批经典谈论加以测试。尽管这个结论是错误的
但这还不足以证明论坛上的帖子都不是经典。还有一点关于m程序提速的这样说到:“在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执行循环次数少的,内环执行循环次数多的。这样可以显著提高速度。” n=1000;
A = ones(1000)*13;
for k=1:n
tic
for i=1:10
for j=1:1000
A(i,j)=A(i,j)*15;
end
end
t1(k)=toc;
tic
for i=1:1000
for j=1:10
A(i,j)=A(i,j)*16;
end
end
t2(k)=toc;
end
t2(t1>10^9)=[];
t1(t1>10^9)=[];
t1(t2>10^9)=[];
t2(t2>10^9)=[];%去除外界因素影响所产生的寄点
plot(1:size(t1,2),t1,'r',1:size(t1,2),t2)
由这个时间图可以看出for循环的嵌套顺序对于速度是有影响的,虽然相对来说差别不是很大,但是毕竟论坛上的观点是正确的。至于他所说的“显著”二字就没必要加上了。此论坛还有一些提速的观点列举如下:“遵守Performance Acceleration的规则
关于什么是“Performance Acceleratio n”请参阅matlab的帮助文件。我只简要的将
其规则总结如下7条: