与'str2func`相比,`eval`的性能来评估字符串中的函数

时间:2017-09-12 15:09:10

标签: matlab performance eval

evalstr2func都能够评估字符串f.e表示的函数。 f='a^x+exp(b)+sin(c*x)+d'

  • 使用eval

    y = eval(f)
    

    或(由rahnema1建议)

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

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

哪种方法都具有最佳性能?

说明

请注意,此基准测试的灵感来自this question

请注意,我知道使用evalstr2func通常是不良做法[1] [2](如评论中所述)。

2 个答案:

答案 0 :(得分:6)

简答:使用str2func

<强>基准

基准测试将评估N的{​​{1}}个不同值的函数。

x

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

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 vs str2func(没有函数句柄):结果显示即使对函数进行一次评估,使用{{1}也要快50%左右比eval(没有函数句柄)。对于大量评估,str2func可能快约100倍(取决于您正在评估的功能)。

eval vs str2func(带功能句柄): str2func对于单次评估比eval慢约100%,但变为对于大量评估来说几乎同样快(eval慢了约5%)。

带有和不带函数句柄的

str2func请注意,对于单个评估,使用eval创建函数句柄比直接评估它要慢约50%。

结论: eval总是比eval快。

答案 1 :(得分:1)

在以下基准测试中,创建了一组函数句柄,并将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

八度结果:

两种方法没有区别。