The performance of `eval` compared to` str2func` for evaluating a function from a string

evaland str2funcboth can evaluate the function represented by the string, fe f='a^x+exp(b)+sin(c*x)+d':

  • Usage eval:

    y = eval(f)
    

    or (suggested by rahnema1)

    fHandle = eval(['@(x, a, b, c, d) ' f]);
    y = fHandle(x, a, b, c, d);
    
  • Usage str2func:

    fHandle = str2func(['@(x, a, b, c, d) ' f]);
    y = fHandle(x, a, b, c, d);
    

Which of the two methods has the best performance?

Notes

Please note that this test is based on this question .

Note that I know that using evaland is str2funcoften bad practice [1] [2] (as indicated in the comments).

+4
source share
2 answers

Short answer: use str2func.

Benchmark

N 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

enter image description here enter image description here enter image description here

str2func vs eval ( ): , , 50% str2func, eval ( ). str2func 100 ( , ).

str2func vs eval ( ): eval 100% , str2func , (eval ~ 5% ).

eval : , eval 50% , .

: str2func , eval.

+6

, eval str2func . + - .

n = 16;
op=char((dec2bin(0:2^n-1)-48)*2+43);
vars= 'a':'z';
v = vars(1:n+1);
s(1:2^n,1:2:2*n+1)=repmat(v,2^n,1);
s(:,2:2:end)=op;

h=repmat(['@(' sprintf('%c,',v(1:end-1)) v(end) ')'],2^n,1);
farray=[h,s];
tic
for k = 1:2^n
    f = eval(farray(k,:));
end
toc

tic
for k = 1:2^n
    f = str2func(farray(k,:));
end
toc

:

.

+1

Source: https://habr.com/ru/post/1685542/


All Articles