arrays qui va - arrayfun peut être significativement plus lent qu'une boucle explicite dans matlab. Pourquoi?
Considérez le test de vitesse simple suivant pour arrayfun
:
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
Sur ma machine (Matlab 2011b sur Linux Mint 12), la sortie de ce test est:
Elapsed time is 1.020689 seconds.
Elapsed time is 9.248388 seconds.
Qu'est-ce que le?!? arrayfun
, tout en admettant une solution plus propre, est un ordre de grandeur plus lent. Qu'est-ce qui se passe ici?
En outre, j'ai fait un test similaire pour cellfun
et trouvé qu'il était environ 3 fois plus lent qu'une boucle explicite. Encore une fois, ce résultat est le contraire de ce à quoi je m'attendais.
Ma question est: Pourquoi arrayfun
et cellfun
sont- cellfun
tellement plus lents? Et étant donné cela, y a-t-il de bonnes raisons de les utiliser (autre que de rendre le code bien paraître)?
Note: Je parle ici de la version standard de arrayfun
, PAS de la version GPU de la boîte à outils de traitement parallèle.
EDIT: Juste pour être clair, je suis conscient que Func1
ci-dessus peut être vectorisé comme indiqué par Oli. Je ne l'ai choisi que parce qu'il donne un simple test de vitesse aux fins de la question.
EDIT: Suite à la suggestion de grungetta, j'ai refait le test avec la feature accel off
. Les résultats sont:
Elapsed time is 28.183422 seconds.
Elapsed time is 23.525251 seconds.
En d'autres termes, il semblerait qu'une grande partie de la différence est que l'accélérateur JIT fait un bien meilleur travail d'accélération de la boucle for
explicite que celle de arrayfun
. Cela me semble étrange puisque arrayfun
fournit plus d'informations, c'est-à-dire que son utilisation révèle que l'ordre des appels à Func1
pas d'importance. Aussi, j'ai noté que si l'accélérateur JIT est allumé ou éteint, mon système n'utilise jamais qu'un processeur ...