why wrapping with anonymous function speeds up?
Mostrar comentarios más antiguos
I try to understand the rational behind this result. When I wrap a function within an anonymmous function, it runs almost 10 times faster (R2022a, Windows, my PC, slightly less on remote server) !
What's going on ?
testfunctioncall()
function testfunctioncall
nruns = 1e6;
a = 1;
b = 2;
%%
fun = @add;
tic;
for k=1:nruns
c = fun(a, b);
end
t1=toc;
% time with direct 1000000 calls of "add" = 0.729264 [s]
fprintf('time with direct %d calls of "add" = %f [s]\n', nruns, t1);
%%
fun = @(a,b) add(a,b);
tic;
for k=1:nruns
c = fun(a, b);
end
t2=toc;
% time with 1000000 calls of "add" wrapped in anonymous = 0.076203 [s]
fprintf('time with %d calls of "add" wrapped in anonymous = %f [s]\n', nruns, t2);
end % testfunctioncall
%% subfunction
function c = add(a, b)
c = a + b;
end
4 comentarios
That is odd.
I added a bit more cases to see if I could explain it, but I was not able to come up with a reason.
One hypothesis was that perhaps the constants being passed in was allowing some optimization, so I feed in different inputs each time, but that did not make any substantial difference.
The "retry" is there because sometimes timing is a bit odd the first time you do something in MATLAB; sometimes you need to run a second time to get the "sustainable" timing. You can see here that the retry was faster, but not by orders of magnitude like the anonymous function is.
I have seen in the past that using anonymous functions is often considerably slower than @ of a function directly by name. I am not sure what is happening in this case.
testfunctioncall()
function testfunctioncall
nruns = 1e6;
a = rand(nruns,1);
b = rand(nruns,1);
%%
fun = @add;
start = tic;
for k=1:nruns
c = fun(a(k), b(k));
end
t1=toc(start);
% time with direct 1000000 calls of "add" = 0.729264 [s]
fprintf('time with direct %d calls of "add" = %f [s]\n', nruns, t1);
%%
fun = @(a,b) add(a,b);
start = tic;
for k=1:nruns
c = fun(a(k), b(k));
end
t2=toc(start);
% time with 1000000 calls of "add" wrapped in anonymous = 0.076203 [s]
fprintf('time with %d calls of "add" wrapped in anonymous = %f [s]\n', nruns, t2);
fun = @plus;
start = tic;
for k=1:nruns
c = fun(a(k), b(k));
end
t3=toc(start);
fprintf('time with %d calls of "plus" in @ = %f [s]\n', nruns, t3);
start = tic;
for k=1:nruns
c = plus(a(k), b(k));
end
t4=toc(start);
fprintf('time with %d calls of "plus" direct = %f [s]\n', nruns, t4);
start = tic;
for k=1:nruns
c = a(k) + b(k);
end
t5=toc(start);
fprintf('time with %d direct + calls = %f [s]\n', nruns, t5);
fun = @(a,b) add(a,b);
start = tic;
for k=1:nruns
c = fun(a(k), b(k));
end
t2=toc(start);
% time with 1000000 calls of "add" wrapped in anonymous = 0.076203 [s]
fprintf('retry time with %d calls of "add" wrapped in anonymous = %f [s]\n', nruns, t2);
end % testfunctioncall
%% subfunction
function c = add(a, b)
c = a + b;
end
Bruno Luong
el 30 de Mzo. de 2022
Editada: Bruno Luong
el 30 de Mzo. de 2022
Stephen23
el 30 de Mzo. de 2022
A wild stab in the dark: might this have something to do with resolving overloaded functions? Perhaps the anonymous function somehow optimizes selecting the correct function in a way that is not possible with the simple function handle.
Do non-overloaded functions show the same behavior?
Bruno Luong
el 30 de Mzo. de 2022
Respuestas (1)
Fangjun Jiang
el 29 de Mzo. de 2022
Editada: Fangjun Jiang
el 29 de Mzo. de 2022
Don't know the exact reason, but I guess it shows that "annonymous function handle" is faster than "named function handle". It is like macro vs function, or inline vs function call? I noticed that direct function call in this case is even faster.
function testfunctioncall
nruns = 1e6;
a = 1;
b = 2;
%%
fun = @add;
tic;
for k=1:nruns
c = fun(a, b);
end
t1=toc;
% time with direct 1000000 calls of "add" = 0.729264 [s]
fprintf('time with direct %d function handle calls of "add" = %f [s]\n', nruns, t1);
%%
fun = @(a,b) add(a,b);
tic;
for k=1:nruns
c = fun(a, b);
end
t2=toc;
% time with 1000000 calls of "add" wrapped in anonymous = 0.076203 [s]
fprintf('time with %d calls of "add" wrapped in anonymous = %f [s]\n', nruns, t2);
tic;
for k=1:nruns
c = add(a, b);
end
t3=toc;
% time with 1000000 calls of "add" wrapped in anonymous = 0.076203 [s]
fprintf('time with %d function calls of "add" = %f [s]\n', nruns, t3);
end % testfunctioncall
%% subfunction
function c = add(a, b)
c = a + b;
end
Categorías
Más información sobre Introduction to Installation and Licensing en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!