Loops non sono sempre lento. Infatti, prove effettuate da Mathworks ha dimostrato che la velocità di loop è migliorata del 40% a causa del nuovo e migliorato Execution Engine (JIT)
Il miglioramento medio delle prestazioni sui test era 40%. I test consistevano in un codice che utilizzava una gamma di prodotti MATLAB. Sebbene non sia tutte le applicazioni funzionino più velocemente con la riprogettazione, la maggior parte di queste applicazioni ha funzionato almeno il 10% più velocemente in R2015b che in R2015a.
e
Il beneficio delle prestazioni della compilazione JIT è maggiore quando MATLAB codice viene eseguito tempi supplementari e può riutilizzare il codice compilato. Questo accade in casi comuni come per-loop o quando le applicazioni vengono eseguite volte aggiuntive in una sessione MATLAB
Un rapido riferimento delle tre soluzioni:
%% bushmills answer, saved as bushmills.m
function B = bushmills(A,N)
B = zeros(size(A,1),size(A,2)/N);
for i = 1:size(A,2)/N
B(:,i) = mean(A(:,(i-1)*12+1:i*12),2);
end
end
A = rand(1000,300); N = 12;
%% Luis Mendo's answer:
lmendo = @(A,N) squeeze(mean(reshape(x.', N, size(x,2)/N, []))).';
%% Divakar's answer:
divakar = @(A,N) reshape(mean(reshape(A,size(A,1),N,[]),2),size(A,1),[]);
b = @() bushmills(A,N);
l = @() lmendo(A,N);
d = @() divakar(A,N);
sprintf('Bushmill: %d\nLuis Mendo: %d\nDivakar: %d', timeit(b), timeit(l), timeit(d))
ans =
Bushmill: 1.102774e-03
Luis Mendo: 1.611329e-03
Divakar: 1.888878e-04
sprintf('Relative to fastest approach:\nDivakar: %0.5f\nBushmill: %0.5f\nLuis Mendo: %0.5f', 1, tb/td, tl/td)
ans =
Relative to fastest approach:
Divakar: 1.00000
Bushmill: 5.34464
Luis Mendo: 10.73969
L' l'approccio loop (con pre-allocazione) è circa il 40% più veloce rispetto alla soluzione squeeze(mean(reshape(...)))
. La soluzione di Divakar batte entrambi di un miglio.
Potrebbe essere diverso per altri valori di A
e N
, ma non ho ancora testato tutti.
Grazie! Ho apportato una piccola modifica al mio esempio di dati, ma questo era perfetto! Ho provato la trasposizione della matrice e il ', 2' in uno dei miei tentativi ma devo aver incasinato il mio ciclo con i. Funziona perfettamente ora. Grazie ancora per la rapida risposta. – rahulk92
@ rahulk92, ricordarsi di [preallocare la memoria] (http://stackoverflow.com/a/6217182/2338750)! –
modificato ... grazie Stewie! specialmente quando si lavora con array di grandi dimensioni, la preallocazione apporta un enorme effetto. – bushmills