2016-11-22 45 views
3

我在matlab上用for循環播放了一下,我知道經常可以避開它們,在這種情況下,速度要快得多。但是,如果我真的想通過矢量V的所有元素,我做了小測試:Matlab:for向量上的循環。奇怪的速度行爲?

n=50000000; 
V =1:n; 

s1 = 0; 
tic 
for x=V 
    s1 = s1+x; 
end 
toc 

s2 = 0; 
tic 
for ind=1:numel(V) 
    s2 = s2+V(ind); 
end 
toc 

S1等S2是相等的(正常的),但它需要24.63秒的第一個環和僅0.48秒爲第二個。

我對這些數字有點驚訝。它是否已知?有沒有人有任何解釋?

+0

這種語法是新的我 「爲X = V」。也許它與解析這行代碼有關 – User1551892

+0

這種行爲很奇怪。 (儘管第一個循環在我的系統中使用MATLAB 2016a沒有花費太多時間)。我需要1.30〜1.35秒!而第二個循環需要0.60〜0.65秒) –

+0

順便說一句,寫's3 = 0;對於x = 1:50000000,s3 = s3 + x;結束'更快! (s2版本的一半時間) – matheburg

回答

4

這可能是由內存分配造成的。情況1

​​

聲明,創建副本的V。我們爲什麼知道?如果在循環內修改V,則x不會受到影響:它仍將貫穿原始的V值。

另外,在殼體2中的語句,

for ind=1:numel(V)

實際上並不創造矢量1:numel(V)。從help for,

由於從未創建索引向量,所以在for語句中出現冒號表達式時,長循環的內存效率更高。

事實上,不需要分配內存可能會增加速度,至少部分是因爲速度的增加。

要測試這個,讓我們將for ind=1:numel(V)更改爲for ind=[1:numel(V)]。這將強制創建矢量1:numel(V)。然後,運行時間應該與案例1相似,或者確實稍大一點,因爲我們仍然需要使用V(ind)索引到V

這是我的電腦上運行時間:

% Case 1 
n=50000000; 
V =1:n; 
s1 = 0; 
tic 
for x=V 
    s1 = s1+x; 
end 
toc 

% Case 2 
s2 = 0; 
tic 
for ind=1:numel(V) 
    s2 = s2+V(ind); 
end 
toc 

% Case 3 
s3 = 0; 
tic 
for ind=[1:numel(V)] 
    s3 = s3+V(ind); 
end 
toc 

結果:

Elapsed time is 0.610825 seconds. 
Elapsed time is 0.182983 seconds. 
Elapsed time is 0.831321 seconds. 
+0

爲什麼不在第2種情況的運行時間之前增加一個'W = V;'的情況? – matheburg

+0

@matheburg可能是因爲Matlab使用[copy-on-write](http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/),所以沒有「真正的「副本實際上是在這一點上完成的 –

+0

@LuisMendo [1:numel(V)]的例子非常有趣,它看起來像解釋:)你正在運行哪個matlab版本?執行時間的差異在你和我之間是巨大的!在我的情況1和情況3:大約25秒和情況2:0.5秒(在一個全新的MacBook Pro和matlab 2014b上) 編輯:我沒有意識到當我爲「我= V」可以修改循環中的V而不影響循環! – pierremomo