I have function handle myfun I need to evalute
y = feval(myfun, x1, x2)
instead of direct call
y = myfun(x1, x2)
because when reading code in the first syntax I know then myfun is a function handle, and in the second syntax there might be a confusion of what myfun is. So for readability and maintainability I prefer using feval.
Note that myfun is NOT a string or char.
I test the speed and it seems to me there is no speed penalty one way or another.
I even think the presence of feval in the code will help the parser-compiler to have specific code of evaluation this function at the compiation time and not at a decision at the runtime, so in theory feval could be faster.
Is there any argument againts using feval?

9 Comments

feval() is not a keyword, so the parser still has to do name resolution on it. The difference is that the name resolution would determine that it is a function, potentially allowing earlier optimization than the case where it is not known at parse time whether a name passed in is an array or a function handle.
One thing I do not know is whether if you were to use an argument block to enforce that the parameter is a function handle, then would the parser be able to reason about that to be able to hypothetically do the same kind of optimization described above? ... Though surely the cost of deriving that kind of information from an argument block would be higher than the cost of deriving it from doing name resolution.
Some benchmark, the difference is probably smaller than jitter noise, both are pretty fast in absolute.
fevalornot()
feval is 0.780371 % slower feval is 1.22133 % slower feval is 0.930187 % slower direct call is 0.0800922 % slower direct call is 2.23703 % slower direct call is 6.28021 % slower feval is 3.98178 % slower direct call is 3.95643 % slower direct call is 1.18097 % slower direct call is 0.907163 % slower
function fevalornot
fun=@(x) x+1;
for k=1:10
td = timeit(@()testdcall(fun));
tf = timeit(@()testfeval(fun));
if tf < td
fprintf('direct call is %g %% slower\n', 100*(td/tf-1));
else
fprintf('feval is %g %% slower\n', 100*(tf/td-1));
end
end
end
function x = testfeval(fun)
for k=1:1000000
x = feval(fun, 0);
end
end
function x = testdcall(fun)
for k=1:1000000
x = fun(0);
end
end
Paul
Paul on 29 Jul 2023
Do you use feval only for anonynous functions? Or do you use it also for your own m-functions? Do you ever use it for Matlab built-in or toolbox functions? What about nesting anonymous functions, like f(g(x1,x2),h(x1,x2))?
Never occured to me to use feval for anything, so just curious about your usage.
Bruno Luong
Bruno Luong on 29 Jul 2023
Edited: Bruno Luong on 30 Jul 2023
"Do you use feval only for anonynous functions? Or do you use it also for your own m-functions?"
Both, sometime an anonymous wrapper on my own function to pass extra input arguments where the caller don't handle.
If the function supposes to be called many times and it is fast, I avoid nesting since the overhead of MATLAB function calling is not negligible.
Note than calling the same implementation using anonymous function is also slower than standard function on mfile.
"Do you ever use it for Matlab built-in or toolbox functions? "
Rarely, but sometime instead of overloading built-in function with my own, I use function handle to make the switch.
"What about nesting anonymous functions, like f(g(x1,x2),h(x1,x2))?"
Not that I recall.
Rik
Rik on 30 Jul 2023
If I recall correctly, I use this syntax for compatibility reasons, since either old Matlab releases or Octave do not support the direct call syntax. I'm surprised (and glad) to see it makes so little difference.
From feval doc "Introduced before R2006a"
So it exists since forever to my book.
It is quite normal, they want to make it compatible with MATLAB
A surprising number of people still code character vectors for the function name for ode45(), ode15s(), or the optimization functions such as fmincon . I would think it likely that Octave would want to maintain compatibility with that possibility.
Rik
Rik on 31 Jul 2023

I was just saying I'm using feval instead of the direct call method. I don't have my installs handy, so I can't look it up for you when the direct call became possible.

At any rate, feval predates anonymous functions (which were introduced in v7). I can't check right now if v6 already had it, but v6.5 definitely does. (I don't extend the compatibility range of my functions to v6, since it doesn't support && and , which would require a lot of extra work in coding, for just a handful of people globally who would benefit)

Bruno Luong
Bruno Luong on 31 Jul 2023
Edited: Bruno Luong on 31 Jul 2023
@Rik "so I can't look it up for you when the direct call became possible."
When function handle is introduced. never mind this is not relevant to my question

Sign in to comment.

 Accepted Answer

Jan
Jan on 30 Jul 2023

0 votes

I do not see problems with using feval.
There have been a speed penalty in old versions, as far as I remember R2009a. But now the JIT-acceleration seems to remove the overhead automatically.

More Answers (0)

Categories

Find more on Programming in Help Center and File Exchange

Products

Asked:

on 29 Jul 2023

Edited:

on 31 Jul 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!