eval
and str2func
are both able to evaluate a function represented by a string, f.e. f='a^x+exp(b)+sin(c*x)+d'
:
Using eval
:
y = eval(f)
or (suggested by rahnema1)
fHandle = eval(['@(x, a, b, c, d) ' f]);
y = fHandle(x, a, b, c, d);
Using str2func
:
fHandle = str2func(['@(x, a, b, c, d) ' f]);
y = fHandle(x, a, b, c, d);
Which of both methods has the best performance?
Remarks
Note that this benchmark is inspired on this question.
Note that I'm aware that using eval
and str2func
is often bad practice[1][2] (as mentioned in the comments).
Short answer: use str2func
.
Benchmark
The benchmark will evaluate the function for N
different values of x
.
f='a^x+exp(b)+sin(c*x)+d';
Ns = linspace(1, 1000, 20);
timeEval = zeros(size(Ns));
timeEvalHandle = zeros(size(Ns));
timeStr2func = zeros(size(Ns));
for i=1:length(Ns)
N = Ns(i);
timeEval(i) = timeit(@() useEval(f, N));
timeEvalHandle(i) = timeit(@() useEvalHandle(f, N));
timeStr2func(i) = timeit(@() useStr2func(f, N));
end
figure
plot(Ns, timeEval, 'DisplayName', 'time eval');
hold on
plot(Ns, timeEvalHandle, 'DisplayName', 'time eval');
hold on
plot(Ns, timeStr2func, 'DisplayName', 'time str2func');
legend show
xlabel('N');
figure
plot(Ns, timeEval./timeStr2func, 'DisplayName', 'time_{eval}/time_{str2func}');
hold on
plot(Ns, timeEvalHandle./timeStr2func, 'DisplayName', 'time_{eval handle}/time_{str2func}');
legend show
xlabel('N');
figure
plot(Ns, timeEvalHandle./timeStr2func);
ylabel('time_{eval handle}/time_{str2func}')
xlabel('N');
function y = useEval(f, N)
a = 1; b = 2; c = 3; d = 4;
for x=1:N
y = eval(f);
end
end
function y = useEvalHandle(f, N)
a = 1; b = 2; c = 3; d = 4;
fHandle = eval(['@(x, a, b, c, d) ' f]);
for x=1:N
y = fHandle(x, a, b, c, d);
end
end
function y = useStr2func(f, N)
a = 1; b = 2; c = 3; d = 4;
fHandle = str2func(['@(x, a, b, c, d) ' f]);
for x=1:N
y = fHandle(x, a, b, c, d);
end
end
str2func
vs eval
(without function handle): The results show that even for evaluating the function once, it is around 50% faster to use str2func
than eval
(without function handle). For a large number of evaluations, str2func
may be around 100x faster (depending on the function you are evaluating).
str2func
vs eval
(with function handle): eval
is around 100% slower than str2func
for a single evaluation, but becomes are almost equally fast for a large number of evaluations (eval
is ~5% slower).
eval
with and without function handle: Note that for a single evaluation creating a function handle with eval
is ~50% slower than evaluating it directly.
Conclusion: str2func
is always faster than eval
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With