2013-08-28 39 views
5

Quan sát này không quan trọng, vì hiệu suất thời gian lãng phí trên các câu lệnh vòng lặp có thể cao hơn nhiều so với bản thân vòng lặp. Nhưng dù sao, tôi sẽ chia sẻ nó kể từ khi tôi tìm kiếm và không thể tìm thấy một chủ đề về điều này. Tôi luôn luôn có ấn tượng này trước khi phân bổ mảng tôi sẽ lặp lại, và sau đó vòng lặp trên nó, sẽ tốt hơn so với looping trực tiếp trên nó, và quyết định kiểm tra nó. Mã này sẽ được so sánh hiệu quả giữa hai fors này:Hiệu suất báo cáo vòng lặp và phân bổ trước câu lệnh vòng lặp

disp('Pure for with column on statement:') 
tic 
for k=1:N 
end 
toc 

disp('Pure for with column declared before statement:') 
tic 
m=1:N; 
for k=m 
end 
toc 

Nhưng kết quả tôi nhận được là:

Pure for with column on statement: 
Elapsed time is 0.003309 seconds. 
Pure for with column declared before statement: 
Elapsed time is 0.208744 seconds. 

Tại sao các địa ngục vậy? Không nên phân bổ trước nhanh hơn?

Trong thực tế, matlab help for nói:

vòng Long là bộ nhớ hiệu quả hơn khi biểu thức đại tràng xuất hiện trong báo cáo CHO kể từ khi véc tơ chỉ số không bao giờ được tạo ra.

Vì vậy, mâu thuẫn với mong đợi của tôi biểu thức cột vào cho tuyên bố là tốt hơn, bởi vì nó không phân bổ các vector và, vì lý do đó, nhanh.

tôi đã thực hiện kịch bản sau đây để kiểm tra những dịp khác mà tôi cũng sẽ nghĩ rằng sẽ nhanh hơn:

% For comparison: 
N=1000000; 

disp('Pure for loop on cell declared on statement:') 
tic 
for k=repmat({1},1,N) 
end 
toc 

disp('Pure for loop on cell declared before statement:') 
tic 
mcell=repmat({1},1,N); 
for k=mcell 
end 
toc 

disp('Pure for loop calculating length on statement:') 
tic 
for k=1:length(mcell) 
end 
toc 

disp('Pure for loop calculating length before statement:') 
tic 
lMcell = length(mcell); 
for k=1:lMcell 
end 
toc 

disp('Pure while loop using le:') 
% While comparison: 
tic 
k=1; 
while (k<=N) 
    k=k+1; 
end 
toc 

disp('Pure while loop using lt+1:') 
% While comparison: 
tic 
k=1; 
while (k<N+1) 
    k=k+1; 
end 
toc 


disp('Pure while loop using lt+1 pre allocated:') 
tic 
k=1; 
myComp = N+1; 
while (k<myComp) 
    k=k+1; 
end 
toc 

Và timings là:

Pure for loop on cell declared on statement: 
Elapsed time is 0.259250 seconds. 
Pure for loop on cell declared before statement: 
Elapsed time is 0.260368 seconds. 
Pure for loop calculating length on statement: 
Elapsed time is 0.012132 seconds. 
Pure for loop calculating length before statement: 
Elapsed time is 0.003027 seconds. 
Pure while loop using le: 
Elapsed time is 0.005679 seconds. 
Pure while loop using lt+1: 
Elapsed time is 0.006433 seconds. 
Pure while loop using lt+1 pre allocated: 
Elapsed time is 0.005664 seconds. 

Kết luận:

  • Bạn có thể đạt được một chút hiệu suất chỉ bằng cách lặp lại các câu lệnh, nhưng điều đó có thể không đáng kể so với thời gian e for-loop.
  • Đối với các ô, sự khác biệt có vẻ không đáng kể.
  • Tốt hơn là nên phân bổ trước độ dài trước khi thực hiện vòng lặp.
  • Thời gian có hiệu quả tương tự như không phân bổ trước véc-tơ, có ý nghĩa như đã nêu trước
  • Như mong đợi, tốt hơn là tính toán biểu thức cố định trước câu lệnh while.

Nhưng câu hỏi mà tôi không thể trả lời là, về ô, tại sao không có sự khác biệt về thời gian? Các chi phí có thể được ít hơn nhiều so với quan sát? Hoặc nó phải phân bổ các tế bào vì nó không phải là một loại cơ bản như là một đôi?

Nếu bạn biết các thủ thuật khác liên quan đến chủ đề này, hãy điền miễn phí.


Chỉ cần thêm timings để hiển thị các kết quả của biến feature('accel','off') như đã nói trong câu trả lời @ Magla của.

Pure for with column on statement: 
Elapsed time is 0.181592 seconds. 
Pure for with column declared before statement: 
Elapsed time is 0.180011 seconds. 
Pure for loop on cell declared on statement: 
Elapsed time is 0.242995 seconds. 
Pure for loop on cell declared before statement: 
Elapsed time is 0.228705 seconds. 
Pure for loop calculating length on statement: 
Elapsed time is 0.178931 seconds. 
Pure for loop calculating length before statement: 
Elapsed time is 0.178486 seconds. 
Pure while loop using le: 
Elapsed time is 1.138081 seconds. 
Pure while loop using lt+1: 
Elapsed time is 1.241420 seconds. 
Pure while loop using lt+1 pre allocated: 
Elapsed time is 1.162546 seconds. 

Kết quả tại khu vực như mong đợi ...

Trả lời

3

Phát hiện này không có gì để làm với preallocating hay không: nó đề với matlab là cho phép hay không để tính toán mọi thứ với một số lõi. Khi bạn chèn toán tử dấu hai chấm trong câu lệnh for, nó sẽ báo cho MATLAB sử dụng một số lõi (tức là đa luồng).

Nếu bạn đặt tấm thảm trên một lõi chỉ với feature('accel','off'), chênh lệch quan sát được với doubles biến mất. Liên quan đến cells, matlab không sử dụng đa luồng - do đó không có sự khác biệt nào có thể quan sát được (bất kể trạng thái của accel là).

Vòng lặp for được đa luồng khi dấu hai chấm được sử dụng và chỉ khi dấu hai chấm được sử dụng. Các vectơ sau có độ dài tương tự như không tham gia vào một vài lõi:

  • for k = randperm(N)
  • for k = linspace(1,N,N)

nhưng for k = 1:0.9999:N là đa luồng.

Một lời giải thích có thể được tìm thấy trên số matlab's support page này. Nó nói rằng xử lý đa lõi có thể được thực hiện khi "Các phép toán trong thuật toán được thực hiện bởi hàm này được phân chia dễ dàng thành các phần có thể được thực thi đồng thời." Với một toán tử ruột kết, Matlab biết rằng for có thể được phân đoạn.

+0

Bây giờ nó có ý nghĩa ... cảm ơn bạn! – Werner

+3

Làm thế nào Matlab có thể biết trước rằng nó an toàn cho đa luồng một vòng lặp 'for'? Sự hiểu biết của tôi là Matlab sẽ thực sự là các hàm đa luồng như 'fft',' eig', 'svd' và' sort', nhưng để nhận đa luồng trên một vòng lặp yêu cầu hộp công cụ xử lý song song và cấu trúc 'parfor' ... Có tài liệu chính thức nào thảo luận về tính năng này không? –

+0

@Colin T Bowers - vui lòng xem chỉnh sửa. Theo sự hiểu biết của tôi; Hàm 'parfor' được sử dụng để đa luồng nội dung của khối' for'. Ở đây, nó chỉ là cuộc gọi chức năng lặp đi lặp lại được đánh giá. – marsei

Các vấn đề liên quan