這是對你有好處來測試這些東西。但是,你需要學習如何做這些測試以獲得良好的信息。
首先,所花費的時間非常少,所以重複測試總是最好的。其次,使用像timeit這樣的工具。它爲您完成所有工作,消除了許多錯誤來源,儘管它需要將其目標封裝爲函數。
接下來,存在TINY問題。你的測試案例非常小。事實上,代碼花費時間有很多原因。考慮功能開銷和啓動成本。一個函數需要一段時間才能調用,因爲設置和銷燬函數工作區的開銷很大。此外,一個好功能將有錯誤測試,並提供幾個選項。但要做到這一點,它必須檢查是否設置了這些選項。所以花了時間,往往沒有任何價值,因爲你只是想用一些簡單的形式來使用函數。這意味着當你調用函數來向量化一個微小的計算時,它實際上可能需要更多的時間,比如果你只是使用unvectorized form inline。所以小的測試案例往往會引起誤解。 (我將增加一個更大的問題的時間比較,但到那時Marc已經在他的答案中這麼做了,請參閱背心差異以瞭解更大的問題。)
您還應該學會使用bsxfun,優化您正在測試的表單的某些計算。再次,小問題往往不會顯示出很大的速度增益,如果有的話。
接下來,JIT存在一些問題,即在MATLAB中加速以優化某些簡單代碼。如果那個(你看不見的)工具能夠很好地處理你正在測試的代碼,那麼它就會看起來好像循環更快。
這是很好做一些測試,所以讓我們做一個比較。由於你的例子都是主要內聯的,所以我只是圍繞每個案例做一個大循環。這將減少測試錯誤的主要來源之一。
Ktot = 100;
N = 10;
Initial = [zeros(N,1) ones(N,1)];
tic
for k = 1:Ktot
for xpop=1:N
for nvar=1:N
Parent(xpop,nvar) = Initial(nvar,1)+(Initial(nvar,2)-Initial(nvar,1))*rand();
end
end
end
toc
tic
for k = 1:Ktot
Parent = repmat(Initial(:,1),1,N) + rand(N,N).*(repmat(Initial(:,2),1,N)-repmat(Initial(:,1),1,N));
end
toc
你能改善你的矢量化表單嗎?爲什麼兩個repmats,當一個會工作?
tic
for k = 1:Ktot
Parent = repmat(Initial(:,1),1,N) + rand(N,N).*repmat(Initial(:,2)-Initial(:,1),1,N);
end
toc
bsxfun怎麼樣?
tic
for k = 1:Ktot
Parent = bsxfun(@plus,Initial(:,1),bsxfun(@times,rand(N,N),Initial(:,2)-Initial(:,1)));
end
toc
所以,用N = 10和Ktot = 100,我看到倍這樣的:
Elapsed time is 0.003935 seconds.
Elapsed time is 0.012250 seconds.
Elapsed time is 0.008269 seconds.
Elapsed time is 0.004304 seconds.
再次,這是一個小問題。如果我們擴大問題會發生什麼?嘗試N = 100,而不是N = 10.
Elapsed time is 0.131186 seconds.
Elapsed time is 0.031671 seconds.
Elapsed time is 0.027205 seconds.
Elapsed time is 0.019763 seconds.
所以我們看到了一些事情在邏輯上更加整理一些。現在bsxfun變體開始顯示出一些收益。接下來,去到N = 1000
Elapsed time is 12.288608 seconds.
Elapsed time is 3.412531 seconds.
Elapsed time is 2.690691 seconds.
Elapsed time is 1.626599 seconds.
從本質上講,所有這些代碼做同樣的工作,它只是一些在他們如何組織的問題更加有效,而一些有更多的開銷。正如我們在更大的問題中看到的那樣,顯式循環是平坦的。
我希望當'Initial'變大時它可能會改變。 –
如果使用1000的維數而不是10的維數,您會看到相反的結果。 – tashuhka
是的,這是正確的人感謝 – NKN