2017-09-22 45 views
4

我有MATLAB的背景,所以我傾向於矢量化所有東西。然而,朱莉婭,我測試了這兩個功能:朱莉婭 - 爲什麼循環更快

function testVec(n) 
    t = [0 0 0 0]; 
    for i = 1:n 
     for j = 1:4 
      t[j] = i; 
     end 
    end 
end 

function testVec2(n) 
    t = [0 0 0 0]; 
    for i = 1:n 
     t.= [i i i i]; 
    end 
end 

@time testVec(10^4) 
0.000029 seconds (6 allocations: 288 bytes) 
@time testVec2(10^4) 
0.000844 seconds (47.96 k allocations: 1.648 MiB) 

我有兩個問題:

  1. 爲什麼循環更快?
  2. 如果循環確實更快,是否有模仿循環的「智能」矢量化技術?循環的語法很醜,很長。
+1

題外話:我是唯一一個覺得充滿「智能」'bsxfun'矢量化技巧的Matlab代碼實際上難以閱讀嗎?在某些情況下,我們只需要循環,所以它應該很快;) – Gnimuc

回答

4

testVec2方法中,代碼將分配用於保存[i i i i]在你的循環的i每個實例的臨時載體。此分配不是免費的。您可以在計時結果中打印的分配數量中看到這一點。你可以嘗試以下方法:

function testVec3(n) 
    t = [0 0 0 0] 
    for i=1:n 
     t .= i 
    end 
end 
3
  1. 它的引擎蓋下的所有循環。矢量化表達式在Julia和Matlab中被轉換爲循環。最後它是所有循環。在你的特定例子中,正如@sam所說,因爲你正在分配一堆額外的數組,你可以避免,如果你明確地循環。你在Matlab中仍然這麼做的原因是,那麼所有的東西都會被轉換成用高性能語言(可能是C或Fortran)編寫的函數,所以即使在進行額外分配時也是值得的。

  2. 事實上,正如@sam所示。 Here的博客文章告訴你所有你需要知道的關於廣播和環路融合的知識。