提高matlab執行速度
我一開始寫了好幾個for迴圈,從不同的Excel檔案中呼叫資料。後來用MATLAB自帶的“執行並計時”功能,找到了毒瘤的程式碼是讀取Excel中的資料,此操作佔用了我將近80%的時間。然後我優化了一下,儘量減少讀取Excel的次數,程式碼跑的時間立刻就下來了
一、 遵守Performance Acceleration的規則
二、 遵守三條規則
三、 絕招
一、 遵守Performance Acceleration的規則
1、只有使用以下資料型別,matlab才會對其加速: logical,char,int8,uint8,int16,uint16,int32,uint32,double
而語句中如果使用了非以上的資料型別則不會加速,如:numeric,cell,structre,single,function handle,java classes,user classes,int64,uint64
2、matlab不會對超過三維的陣列進行加速。
3、當使用for迴圈時,只有遵守以下規則才會被加速:a、for迴圈的範圍只用標量值來表示;b、for迴圈內部的每一條語句都要滿足上面的兩條規則,即只使用支援加速的資料型別,只使用三維以下的陣列;c、迴圈內只調用了內建函式(build-in function)。
4、當使用if、elseif、while和switch時,其條件測試語句中只使用了標量值時,將加速執行。
5、不要在一行中寫入多條操作,這樣會減慢執行速度。即不要有這樣的語句:
x = a.name; for k=1:10000, sin(A(k)), end;
6、當某條操作改變了原來變數的資料型別或形狀(大小,維數)時將會減慢執行速
度。
7、應該這樣使用復常量x = 7 + 2i,而不應該這樣使用:x = 7 + 2*i,後者會降低
執行速度。(已驗證)
二、 遵守三條規則
1、儘量避免使用迴圈
a、儘量用向量化的運算來代替迴圈操作。最常用的使用vectorizing技術的函式有:All、diff、ipermute、permute、reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cumsum、ind2sub、ndgrid、repmat、sort、sum 等。
請注意matlab文件中還有這樣一句補充:“Before taking the time to
vectorize your code, read the section on Performance Acceleration.
You may be able to speed up your program by just as much using the MATLAB JIT Accelera tor instead of vectorizing.”
b、在必須使用多重迴圈時下,如果兩個迴圈執行的次數不同,則在迴圈的外環執
行迴圈次數少的,內環執行迴圈次數多的。這樣可以顯著提高速度。(已驗證)
2、a、預分配矩陣空間,即事先確定變數的大小,維數。這一類的函式有zeros、ones、cell、struct、repmat等。
b、當要預分配一個非double型變數時使用repmat函式以加速,如將以下程式碼:
A = int8(zeros(100));換成:A = repmat(int8(0), 100, 100);(已驗證)
c、當需要擴充一個變數的大小、維數時使用repmat函式。(已驗證)
3、a、優先使用matlab內建函式,將耗時的迴圈編寫進MEX-File中以獲得加速。b、使用Functions而不是Scripts 。
三、 絕招
你也許覺得下面兩條是屁話,但有時候它真的是解決問題的最好方法。
1、改用更有效的演算法
2、採用Mex技術,或者利用matlab提供的工具將程式轉化為C語言、Fortran語言。
關於如何將M檔案轉化為C語言程式執行,可以參閱本版帖子:“總結:m檔案轉化為c/c++語言檔案,VC編譯”。
一、未進行記憶體預分配
y = 0;
tic;
for i=2:100000;
y(i+1) = y(i)+ randn;
end;
toc
時間已過 0.031222 秒。
二、進行記憶體預分配
y = zeros(100001,1);
tic;
for i=2:100000;
y(i+1) = y(i)+ randn;
end;
toc
時間已過 0.007672 秒。
節約時間=(0.031222-0.007672 )/ 0.031222 =75%
三、進行矩陣計算
y = zeros(100001,1);
tic;
y= cumsum([0;y]);
toc
時間已過 0.000445秒。
節約時間=(0.031222-0.000445 )/ 0.031222 =98.6%