is 'arrayfun' faster much more than 'for' loop?
100 次查看(过去 30 天)
显示 更早的评论
now I have written a function which use a 'for' loop and it runs slowly because of large calculations; If i use 'arrayfun' to replace 'for' loop, the function would run faster much?
1 个评论
Adam
2017-2-9
编辑:Adam
2017-2-9
Simplest way to understand is to implement both options and time them using
doc timeit
I do this regularly when I want to understand which of multiple methods of implementing something is faster. As Walter says below though, if you just want a quick answer arrayfun is usually slower.
回答(3 个)
Walter Roberson
2017-2-9
Typically arrayfun() runs more slowly, because it needs to invoke a function call each time through its internal for loop. There is still a for loop; it is just hidden.
1 个评论
Walter Roberson
2017-2-12
Here is some code to test out various possibilities.
The items are:
- plain for loop
- arrayfun
- if false arrayfun else for loop
- arrayfun_is_faster = false; if arrayfun_is_faster arrayfun else for loop
- retest plain for loop
The code has two outputs: first the ratio of times relative to the plain for loop, and secondly the mean time of each of the groups.
The times will be plotted along with a mark indicating the mean time. The y limits are set the same on all of the plots so you can directly compare the height of the mean lines.
If you have the statistics toolbox a boxplot will be presented as well.
In my test, arrayfun is consistently the slowest, by 30% to 60%.
However, in my tests, the initial test of plain for loop was often the second slowest, even though the for loop logic is copied exactly the same to #3 and #4, measurably slower than re-running the exact same for loop after the other tests were done. Testing for a variable set false was about 1% slower than "if false": slower but not much slower.
Why was the initial running of the plain for loop slower than re-running it later? I notice that even though I re-run the timeit 200 times, the variability of timings on the first probe of plain for loops is much higher than later. I have no explanation for that.
I could hypothesize that the JIT has does not fully optimize until the code has been run a few hundred times (each timeit() call is going to call the actual routine a number of times.)
Jan
2017-2-9
编辑:Jan
2017-2-9
While in all of my tests arrayfun was slower, I have collected these tests in an M-file and run it with every new Matlab release. I'm used to write the for-loop approach at first, add the arrayfun afterwards and compare the results and speed by unit-testing. Then I comment out the slower method.
This demands for an exhaustive commenting, because it is too confusing, if somebody finds commented code some years later and has no idea, why it is not used. Or imagine that the arrayfun approach is modified later, but the commented for approach is not. This will confuse a reader massively, if it is not explained clearly.
Care for optimizing the bottlenecks only. So called premature optimization can increase the debug time dramatically, such that the total program time (programming + debugging + documenting + running) might increase.
Summary: Try it.
3 个评论
Arjan Lampe
2020-5-6
It seems arrayfun is much, much more slower. Or am I messing something up?
A simple (too simple?) test. Make some test function:
testf.m:
function m = testf(m)
%TESTF Summary of this function goes here
% Detailed explanation goes here
for c_m = 1:numel(m)
m(c_m) = sqrt(m(c_m));
end
end
And then:
>> m = rand(15)
>> tic; for ii = 1:1000000; testf(m); end; toc
Elapsed time is 1.405036 seconds.
>> tic; for ii = 1:1000000; arrayfun(@sqrt,m); end; toc
Elapsed time is 116.857802 seconds.
That is a factor 83 slower...
2 个评论
Evan Voyles
2021-1-15
I think the factor for which it is slower largely depends on what function you are applying to the array. For example, I tested arrayfun vs a forloop, squaring the elements, and the speed difference was a factor of two. While this is concrete evidence that we should always use for loops instead of arrayfun, it's obvious that the benefit varies.
It's kind of sad because writing a single command arrayfun is so much more appealing that writing out the full for loop. I guess that's the sacrifice that we make for performance ;)
Bruno Luong
2021-1-15
twice only? Put it in a function to have JIT correctly speed up the loop
function forloopvsarrayfun
x = rand(1,1e6);
tic
y = zeros(size(x));
for i=1:length(x)
y(i) = x(i).^2;
end
t1=toc;
tic
y = arrayfun(@(x) x.^2, x);
t2=toc;
fprintf('for loop time = %g\n', t1);
fprintf('arrayfun time = %g\n', t2);
fprintf('arrayfun time is %g time slower\n', t2/t1);
end
This is the result with R2020B
for loop time = 0.0042138
arrayfun time = 1.99038
arrayfun time is 472.348 time slower
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Loops and Conditional Statements 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!