arrayfun może być znacznie wolniejszy niż jawna pętla w matlab. Czemu?
Rozważmy następujący prosty test prędkości dlaarrayfun
:
T = 4000;
N = 500;
x = randn(T, N);
Func1 = @(a) (3*a^2 + 2*a - 1);
tic
Soln1 = ones(T, N);
for t = 1:T
for n = 1:N
Soln1(t, n) = Func1(x(t, n));
end
end
toc
tic
Soln2 = arrayfun(Func1, x);
toc
Na moim komputerze (Matlab 2011b na Linux Mint 12) wynikiem tego testu jest:
Elapsed time is 1.020689 seconds.
Elapsed time is 9.248388 seconds.
Co?!?arrayfun
, chociaż co prawda czystsze, wyglądające rozwiązanie, jest o rząd wielkości wolniejsze. Co tu się dzieje?
Ponadto wykonałem podobny testcellfun
i okazało się, że jest około 3 razy wolniejszy niż pętla jawna. Ponownie, ten wynik jest przeciwieństwem tego, czego oczekiwałem.
Moje pytanie brzmi: Dlaczego sąarrayfun
icellfun
o wiele wolniej? Czy biorąc pod uwagę to, czy są jakieś dobre powody, aby z nich korzystać (poza tym, aby kod wyglądał dobrze)?
Uwaga: Mówię o standardowej wersjiarrayfun
tutaj NIE wersja GPU z przybornika przetwarzania równoległego.
EDYTOWAĆ: Żeby było jasne, jestem tego świadomyFunc1
powyżej można wektoryzować, jak wskazuje Oli. Wybrałem go tylko dlatego, że daje to prosty test prędkości dla celów rzeczywistego pytania.
EDYTOWAĆ: Podążając za sugestią grungetty, ponownie wykonałem testfeature accel off
. Wyniki są następujące:
Elapsed time is 28.183422 seconds.
Elapsed time is 23.525251 seconds.
Innymi słowy, wydaje się, że duża część różnicy polega na tym, że akcelerator JIT znacznie lepiej przyspiesza wyraźnefor
pętla niż toarrayfun
. Wydaje mi się to dziwnearrayfun
faktycznie dostarcza więcej informacji, tj. jego użycie ujawnia, że kolejność wywołańFunc1
nieważne. Zauważyłem również, że bez względu na to, czy akcelerator JIT jest włączony, czy nie, mój system używa tylko jednego procesora ...