arrayfun может быть значительно медленнее, чем явный цикл в matlab. Зачем?
Рассмотрим следующий простой тест скорости для: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
На моей машине (Matlab 2011b на Linux Mint 12) результат этого теста:
Elapsed time is 1.020689 seconds.
Elapsed time is 9.248388 seconds.
Что за?!?arrayfun
Хотя, по общему признанию, решение выглядит более чистым, оно на порядок медленнее. Что здесь происходит?
Далее я сделал похожий стиль теста дляcellfun
и обнаружил, что он примерно в 3 раза медленнее, чем явный цикл. Опять же, этот результат противоположен тому, что я ожидал.
Мой вопрос: Почемуarrayfun
а такжеcellfun
намного медленнее? И учитывая это, есть ли веские причины для их использования (кроме как для того, чтобы код выглядел хорошо)?
Примечание: яя говорю о стандартной версииarrayfun
здесь, а не версия GPU из набора инструментов параллельной обработки.
РЕДАКТИРОВАТЬ: Просто чтобы быть ясно, яя знаю, чтоFunc1
выше может быть векторизовано, как указано Оли. Я выбрал его только потому, что он дает простой тест скорости для целей настоящего вопроса.
РЕДАКТИРОВАТЬ: Следуя предложению Грунгетты, я снова сделал тест сfeature accel off
, Результаты:
Elapsed time is 28.183422 seconds.
Elapsed time is 23.525251 seconds.
Другими словами, может показаться, что большая часть различий заключается в том, что JIT-ускоритель значительно ускоряет работу явногоfor
петля, чем это делаетarrayfun
, Это кажется странным для меня, так какarrayfun
фактически предоставляет больше информации, т.е. его использование показывает, что порядок вызововFunc1
не имеет значения. Также я отметил, что независимо от того, включен ли JIT-ускоритель, моя система использует только один процессор ...