1

我在 matlab 的其他人的代码中遇到了函数eval(expression)的使用:例如:

for n = 1 : 4
sn = int2str( n) ;
eval( [ 'saveas( fig'  sn  ', [ sName' sn ' ], ''fig'' ) ' ] );
end

Matlab Help 中的 MathWorks 资料指出:

与其他 MATLAB 函数和语言结构相比,eval 函数的许多常见用途效率较低,并且更难阅读和调试。

在此之后,我发现这个函数在许多其他程序语言中都有使用,例如 Python、JavaScript、PHP。

所以我有几个问题:

  1. 这个函数的使用会影响我的代码的性能吗?
  2. 如果它会减慢执行速度,为什么会发生?
  3. 如果每次调用都会减慢执行速度,原则上使用这个函数的原因是什么?
4

4 回答 4

6

eval功能很危险,您真正需要它的示例很少。例如,如果将图形句柄存储在数组等中并编写fig(1),则可以轻松重写您提供的代码fig(2)

for n = 1:4
  filename = sprintf('sName%d', n);
  saveas(fig(n), filename, 'fig');
end

这更清晰,使用更少的字符,可以通过 Matlab 编辑器的 linter 进行分析,如果(何时)您需要扩展代码,则更容易修改,并且不太容易出现奇怪的错误。

根据经验,eval除非您真的知道自己在做什么(即您正在编写一个复杂的 Lisp 宏或其他等同于操作该语言的 AST 的东西 - 如果您不知道那是什么),否则您永远不应该使用任何语言意味着,您可能不需要使用eval)。

几乎总是有更清晰、更有效和更不危险的方法来实现相同的结果。通常,可以将调用eval替换为某种形式的递归高阶函数或循环。

于 2012-04-22T22:13:07.740 回答
5
  1. 在这里使用 eval 肯定会比非 eval 版本慢,但它很可能不会成为您代码中的瓶颈。但是,性能只是一个问题,维护(包括调试)以及可读性是其他问题。
  2. 出现减速是因为 Matlab 使用 JIT 编译器,并且eval无法优化行。
  3. 在大多数情况下,评估的使用是由于缺乏关于合适的 Matlab 功能的知识。在这种特殊情况下,问题在于图形句柄存储在fig1通过调用的变量名中fig4。如果它们被存储在一个名为fig, ie fig(1)etc 的数组中,那eval将是不必要的。

编辑这是 Loren Shure 撰写的两篇关于为什么eval在 Matlab 中应避免使用的优秀文章。逃避 eval更多关于 eval的内容。

于 2012-04-22T22:12:48.397 回答
1

这是另一个含义:

当你编译一个使用 的程序时eval,你必须放置 pragma 告诉编译器需要一些函数。例如:

此代码将编译并运行良好:

 foo()

但这需要添加一个编译指示:

 %#function foo
 eval('foo()') 

否则会遇到运行时问题。

于 2012-04-23T06:52:39.677 回答
1

在大多数情况下,速度变慢是因为必须将字符串解析为实际代码。如果谨慎使用,这不是什么大问题,但是如果您发现自己在循环代码(显式循环或 JavaScript 之类的东西setInterval())中使用它,那么您的性能将大幅下降。

我见过的eval可以做得更好的常见用途是:

  • 在不了解[]符号的情况下访问属性名称
  • 基于参数名称调用函数,可以改为使用switch(更安全,防止代码注入风险)
  • 当它们应该是数组时访问名为var1,var2的变量var3

老实说,我认为我从来没有遇到过一种情况,这eval是解决问题的唯一方法。我想你可以把它比作goto它是程序结构的替代品,或者作为一个临时解决方案来测试一个程序,然后再花时间让它以最佳方式工作。

于 2012-04-22T22:12:30.203 回答