首先說說matlab
與其他語言的差異:例如對於c或者c++來說,只要演算法的思想不變、採用的資料結構相同,不同人寫出來的語句在效率上一般不會產生太大的差別。所以,對於c來說,程式的好壞一般由演算法來決定。但是,在matlab中,同樣的演算法、同樣的結構、同樣的流程,如果採用的語句不一樣,在效率上就會大大不同。所以,我認為,使用matlab比使用其他語言更加困難,也顯得matlab更難以掌握。另外,由於matlab在儲存管理上的不便,使得在同時提高時空兩域的效率變得更加困難,特別是在空間上(因為在時間上matlab提供了profiler這個非常有用的工具,但是在空間上就沒有)。當需要處理大量的資料時,精簡時空兩域的程式語句就尤為重要了。
空間上:
1. 建議使用a = logical(sparse(m,n)),不建議使用 a = sparse(false(m,n)),兩者結果一樣,但是後者生成m×n的臨時矩陣,浪費空間,且當m、n很大時,後者不一定能申請成功;
2. 使用sparse幾點注意:
a) 只能用在二維以下的矩陣上;
b) 由於matlab按照「先行後列」的方式讀取資料(即先把第一列所有行讀取完以後再讀取第二列的各行),因此定義稀疏矩陣時,最好「行數》列數」,這樣有利於定址和空間的節省(自己試試a=sparse(10,5); whos a和b= sparse(5,10);whos b就知道了);
c) 對大型矩陣用sparse非常有效(不但節省空間,而且加快速度,強烈推薦!這在動態申請陣列空間的時候尤其方便,當然了,陣列不是太大的時候也可以使用eval即字串的方法),但對小型矩陣使用反而增加儲存量(自己試試a=false(5,1); whos a和b=logical(sparse(5,1));whos b就知道了),相信這是由稀疏矩陣需要儲存額外的資訊引起的。
3. 盡量按照精度來選擇資料的型別,例如,如果只需用到0-255之間的整數,則定義矩陣為uint8型就ok了,定義方式:a = zeros(10,10,』uint8』);可以用intmin(『uint8』)和intmax(『uint8』)返回該種型別的最值。
時間上:
1. 在for迴圈中,清零操作用賦值語句 a = b,其中b是在for迴圈外的乙個同a大小一樣的全0陣,不要使用a(:) = 0;但這樣會大大影響後面的逐點運算速度。這個問題要請教高手,那就是「個別語句的改動會引起其他語句的執行速度」。例如分別執行3萬多次下面**,但執行時間有較大差別:
ilen = length(find(alregion)); % 0.58 s
if ilen >= ithreshold_2 % 0.05 s
…end
和ilen = sum(alregion); % 0.37 s
if ilen >= ithreshold_2 % 0.40 s
…end
2. find函式較慢,可用logical函式代替,但是,當需要取得滿足條件的下標時,就無法使用logical函式,這已經在我之前的帖子中提及過。不過,大家有沒有想過,連find函式都可以進行優化的,方法是用「基本矩陣進行顯式邏輯引用」來代替find。例如,假設矩陣a是乙個61*73*20的三維邏輯矩陣,如果用下面的語句迴圈3萬多次,需要的時間是13 s :
b = find(a == true);
如果採用下面的方法,則只需要不到0.7 s:
首先定義乙個索引矩陣:
a3icubicidx = uint32(1:itotalvoxel); % uint32可以根據需要調整,這裡省略了條件判斷
a3icubicidx = reshape(a3icubicidx, [ivollen, ivolwdh, ivolhgh]);
然後在迴圈中寫以下**:
a3itemp = a3icubicidx(ixmin:ixmax,iymin:iymax,izmin:izmax);
b = aitemp(a(ixmin:ixmax,iymin:iymax,izmin:izmax));
當然了,改進的前提是知道矩陣a的非零元(即值為true的元素)大致的分布,也就是能夠求出ixmin:ixmax,iymin:iymax,izmin:izmax這個範圍。現在終於明白並體會到cwit所說的「連num2str都優化過」的含義了。
3. 不斷優化**,例如corrcoef函式,matlab自帶的corrcoef函式求整個矩陣所有列的相關係數,因為我只需要求出某一列跟其他各列的相關係數,所以參照corrcoef函式自己寫了乙個,不但把速度提了上去,而且還發現了:repmat(5,100,1)的速度並不比ones(100,1)*5 快,另外,別小看乙個小矩陣的轉置操作,當迴圈次數很大的時候,有沒有轉置就相差很遠了。
4. 使用邏輯運算子&、| 時,兩個操作物件最好是logical型別,否則速度會減慢。
5. 二維矩陣轉置操作可以用以下三種方法進行,三者的效率基本一樣(時空),如果遇到三維以上的矩陣要轉置,用permute命令較為方便:
a) a = a』;
b) a = permute(a,[2,1]);
c) a = shiftdim(a,1);
6. 「使用eval方式動態儲存多個一維陣列」比「使用二維陣列動態儲存多個一維陣列」要快,即:eval(['a_', num2str(k),' = b;']);比 a(k,:) = b; 快,其中b是乙個一維陣列,k表示迴圈次數。注:並非所有b都進行儲存,只儲存滿足某個條件的b,另外,對預申請空間a不成功,這是對結論的補充說明。值得注意的是,如果對b是乙個稀疏的一維陣列,則eval方式的優勢蕩然無存,當k增大時反而增加系統開銷。
7. 當矩陣很大時,利用a(:,k+1:end)=;去掉多餘元素操作時會減慢程式的執行,因此,如果後續處理中沒有用到這些多餘元素,則沒有必要使用這個語句,即不管就是了。
8. 當需要對很大的乙個矩陣進行操作時,可以考慮使用迴圈來完成。例如corrcoef函式,如果處理的物件矩陣a是100*180時(即對100個列向量求它們兩兩之間的相關程度,假設需要的只是前面99個與第100個向量的相關係數,其他不需要用到),直接用corrcoef(a)會比較慢,這時候可以考慮把矩陣a分為5個部分,每個子塊與第100個向量進行相關,這樣速度會更快。
9. 區域性比較、賦值比全域性比較、賦值要快(呵呵,這是廢話),假設a、b都是三維邏輯矩陣,如果只想對某個區域性(例如x_1:x_2,y_1:y_2,z_1:z_2這個立方體)進行比較和賦值,則推薦使用b(x_1:x_2,y_1:y_2,z_1:z_2) = b(x_1:x_2,y_1:y_2,z_1:z_2) & ~a(x_1:x_2,y_1:y_2,z_1:z_2),這比b(a) = false或b = b&~a速度上都要快不少。
提高VM執行速度
在你使用vm5的時候是否遇到過這樣的情況。物理機效能很好,記憶體豐富,但vm執行起來速度很慢。這是因為在vmware5的版本中增加了乙個新的功能,系統會為你建立乙個.vmem的檔案,這個檔案的大小就是你定義的虛擬機器系系統記憶體大小。這個檔案用作記憶體的交換空間。vm5中只是用16兆物理記憶體,其他...
如何提高selenum的執行速度
selenum的執行速度會受到多方面的影響,如網速,操作步驟的繁瑣性,頁面的載入速度以及指令碼中設定的等待時間,執行的執行緒數等,所以不能從單方面去追求速度。要確保穩定性,能穩定的實現回歸測試超市關鍵。我們可以從以下幾個方面提高執行效率 化繁為簡,減少操作步驟 如經過三四步才開啟的網頁,可以直接通過...
如何提高FPGA的執行速度
對於設計者來說,當然希望我們設計的電路的工作頻率 在這裡如無特別說明,工作頻率指fpg 內的工作頻率 盡量高。我們也經常聽說用資源換速度,用流水的方式可以提高工作頻率,這確實是乙個很重要的方法,今天我想進一步去分析該如何提高電路的工作頻率。我們先來分析下是什麼影響了電路的工作頻率。我們電路的工作頻率...