La maggior parte dei consigli che stai leggendo, incluso il post sul blog di Loren, si riferisce probabilmente alle vecchie versioni di MATLAB, per le quali bsxfun
era un po 'più veloce di repmat
. In R2013b (vedere la sezione "Prestazioni" nel collegamento), repmat
è stato reimplementato per fornire grandi miglioramenti delle prestazioni quando applicato a argomenti numerici, char e logici. Nelle versioni recenti, può avere all'incirca la stessa velocità di bsxfun
.
Per quel che vale, sulla mia macchina con R2014a ricevo
m = 1e5;
n = 100;
A = rand(m,n);
frepmat = @() A - repmat(mean(A),size(A,1),1);
timeit(frepmat)
fbsxfun = @() bsxfun(@minus,A,mean(A));
timeit(fbsxfun)
ans =
0.03756
ans =
0.034831
modo che appaia come bsxfun
è ancora un pochino più veloce, ma non molto - e sulla vostra macchina sembra il contrario è il caso . Naturalmente, è probabile che questi risultati varieranno di nuovo, se si modifica la dimensione di A
o l'operazione che si sta applicando.
Ci possono essere altri motivi per preferire una soluzione rispetto all'altra, come l'eleganza (preferisco lo bsxfun
, se possibile).
Edit: commentatori hanno chiesto per un motivo specifico per preferire bsxfun
, il che implica che si potrebbe utilizzare meno memoria di repmat
evitando una copia temporanea che repmat
non lo fa.
Non penso che questo sia effettivamente il caso. Ad esempio, aprire Task Manager (o l'equivalente in Linux/Mac), guardare i livelli di memoria, e il tipo:
>> m = 1e5; n = 8e3; A = rand(m,n);
>> B = A - repmat(mean(A),size(A,1),1);
>> clear B
>> C = bsxfun(@minus,A,mean(A));
>> clear C
(Regolare m
e n
fino a quando i salti sono visibili nel grafico, ma non così grande che si esaurito la memoria).
vedo esattamente lo stesso comportamento sia repmat
e bsxfun
, che è quella memoria aumenta gradualmente verso il nuovo livello (sostanzialmente raddoppiare la dimensione A
) senza ulteriore picco temporaneo.
Questo vale anche se l'operazione viene eseguita sul posto.Ancora una volta, guardare la memoria e tipo:
>> m = 1e5; n = 8e3; A = rand(m,n);
>> A = A - repmat(mean(A),size(A,1),1);
>> clear all
>> m = 1e5; n = 8e3; A = rand(m,n);
>> A = bsxfun(@minus,A,mean(A));
nuovo, vedo esattamente lo stesso comportamento sia repmat
e bsxfun
, che è che la memoria raggiunge un picco (sostanzialmente raddoppiare la dimensione A
), e poi ricade al livello precedente.
Quindi temo di non vedere molte differenze tecniche in termini di velocità o memoria tra repmat
e bsxfun
. La mia preferenza per bsxfun
è in realtà solo una preferenza personale in quanto sembra un po 'più elegante.
Per me l'approccio bsxfun è sempre più veloce, anche per gli array più grandi. (Matlab 2014a) – thewaywewalk
Per me (R2014b) vince anche bsxfun. Quale versione di matlab usi? –
L'ho provato sia nel 2014 che nel 2014b. Il sistema operativo utilizzato potrebbe fare la differenza? Sono su OSX. – user1337