1

matlabの他の誰かのコードで関数eval(expression)の使用に遭遇しました:例:

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

MatlabヘルプのMathWorksのものは、次のように指摘しています。

eval関数の一般的な使用法の多くは、他のMATLAB関数や言語構造よりも効率が低く、読み取りやデバッグが困難です。

この後、Python、JavaScript、PHPなど、他の多くのプログラム言語でこの関数が使用されていることがわかります。

だから私はいくつかの質問があります:

  1. この関数の使用は、コードのパフォーマンスに影響しますか?
  2. 実行速度が低下する場合、なぜ発生するのですか?
  3. 呼び出されるたびに実行速度が低下する場合、原則としてこの関数を使用する理由は何ですか?
4

4 に答える 4

6

このeval関数は危険であり、実際に必要な例はほとんどありません。たとえば、Figureのハンドルを配列などに格納して書き込むとfig(1)、指定したコードを簡単に書き直すことができます。fig(2)

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

これはより明確で、使用する文字が少なく、Matlabエディターのリンターで分析でき、コードを拡張する必要がある場合(いつ)でも簡単に変更でき、奇妙なバグが発生しにくくなります。

経験則として、自分evalが何をしているのかを本当に理解していない限り、どの言語でも使用しないでください(つまり、複雑なLispマクロまたは言語のASTを操作するのと同等の何かを書いている場合-それが何であるかわからない場合つまり、おそらくを使用する必要はありませんeval)。

ほとんどの場合、同じ結果を達成するためのより明確で、より効率的で、危険性の少ない方法があります。多くの場合、への呼び出しは、何らかの形式の再帰高階関数、またはループevalに置き換えることができます。

于 2012-04-22T22:13:07.740 に答える
5
  1. ここでevalを使用すると、非evalバージョンよりも確かに遅くなりますが、コードのボトルネックにはならない可能性があります。ただし、パフォーマンスは1つの問題にすぎず、メンテナンス(デバッグを含む)と読みやすさは他の問題です。
  2. MatlabはJITコンパイラを使用しており、eval回線を最適化できないため、速度が低下します。
  3. ほとんどの場合、評価の使用は、代わりに適切なMatlab機能に関する知識が不足しているためです。この特定のケースでは、問題は、Figureハンドルがfig1を介して呼び出される変数名に格納されることfig4です。figそれらが、すなわちfig(1)などと呼ばれる配列に格納されていた場合は、eval不要でした。

編集evalここに、Matlabで避けるべき理由についてのLorenShureによる2つの優れた記事があります。evalの回避、およびevalの詳細

于 2012-04-22T22:12:48.397 に答える
1

ほとんどの場合、文字列を実際のコードに解析する必要があるため、速度が低下します。これは、控えめに使用すればそれほど大きな問題ではありませんが、ループするコード(明示的なループまたはJavaScriptのようなものsetInterval())で使用していることに気付いた場合は、パフォーマンスが大幅に低下します。

私が見た一般的な使用法は、次のevalとおりです。

  • []表記を無視してプロパティ名にアクセスする
  • 引数名に基づいて関数を呼び出す。これは、代わりにswitch(より安全で、コードインジェクションのリスクを防ぐ)で実行できます。
  • 代わりに配列である必要がある場合にvar1、、、var2のような名前の変数にアクセスするvar3

eval正直なところ、問題を解決する唯一の方法である単一の状況に遭遇したことはないと思います。gotoプログラム構造の代わりになる、またはプログラムを最適に動作させるために時間を費やす前にプログラムをテストするための一時的な解決策として役立つという点で、あなたはそれを例えることができると思います。

于 2012-04-22T22:12:30.203 に答える
1

別の意味があります:

を使用するプログラムをコンパイルするときはeval、いくつかの関数が必要であることをコンパイラーに通知するプラグマを配置する必要があります。例えば:

このコードはコンパイルされ、正常に実行されます。

 foo()

しかし、これにはプラグマを追加する必要があります。

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

そうしないと、実行時の問題が発生します。

于 2012-04-23T06:52:39.677 に答える