循環在Matlab不再是令人擔心的事情,或避免本身。
當然,在使用它們時應該非常小心,但是JIT可以處理多種循環,甚至可以超越內建函數來提高性能。
請看下面的測試案例:
clc
m = 512; n = 384;
p = 5; q = 3;
A = rand(m,n,p); % some sample data
B = rand(m,n,q); % some sample data
%% non-loop approach
tic
A2 = reshape(A,[],p);
B2 = reshape(B,[],q);
C2 = arrayfun(@(ii) A2(ii,:)'*B2(ii,:),1:m*n,'uni',false);
C0 = permute(reshape(cell2mat(C2),p,q,m,n),[3 4 1 2]);
toc
%% looped approach, simplest
tic
C = zeros(m,n,p,q);
for mm = 1:m
for nn = 1:n
C(mm,nn,:,:) = ...
squeeze(A(mm,nn,:))*squeeze(B(mm,nn,:)).';
end
end
toc
% check for equality
all(C0(:) == C(:))
%% looped approach, slightly optimized
tic
C = zeros(m,n,p,q);
pp = zeros(p,1);
qq = zeros(1,q);
for mm = 1:m
for nn = 1:n
pp(:) = A(mm,nn,:);
qq(:) = B(mm,nn,:);
C(mm,nn,:,:) = pp*qq;
end
end
toc
% check for equality
all(C0(:) == C(:))
%% looped approach, optimized
tic
C = zeros(p,q,m*n);
A2 = reshape(A,[],p);
B2 = reshape(B,[],q);
for mn = 1:m*n
C(:,:,mn) = A2(mn,:).'*B2(mn,:);
end
C = permute(reshape(C, p,q,m,n), [3,4,1,2]);
toc
% check for equality
all(C0(:) == C(:))
結果:
Elapsed time is 3.955728 seconds.
Elapsed time is 21.013715 seconds.
ans =
1
Elapsed time is 1.334897 seconds.
ans =
1
Elapsed time is 0.573624 seconds.
ans =
1
無論表現,我也覺得最後一種情況很多比非循環情況下更爲直觀性和可讀性。
哇,這是一個很酷的事情。我不知道MATLAB能做這種事情。我會嘗試一下,如果它實際上以這種方式工作,速度更快,我會用它;) – 2012-07-29 11:31:46
@rody_o:+1進行全面比較,再加上我無法就JIT加速達成一致 – Amro 2012-07-29 22:05:06