2012-04-22 21 views
1

私はMathWorks社のMATLABで他人のコード内の関数の使い方のeval(表現)で発生しました:MATLABコードでのeval( 'expression')の使用と影響?

Matlabのヘルプで

MathWorks社のものが指摘

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

多くの一般的な例 eval関数の使用は効率が悪く、他のMATLAB関数や言語構成よりも読み込みとデバッグが難しくなります。

この後、私はこの機能を他の多くのプログラム言語、つまりPython、JavaScript、PHPなどで使用しています。

だから私はいくつかの質問している:この機能の

  1. ウィルの使用量は、私のコードのパフォーマンスにenfluencedこと?
  2. 実行が遅くなる場合、なぜそれが発生しますか?
  3. 呼び出されるたびに実行が遅くなる場合、この機能を使用する理由は何ですか?
+0

これはMATLABの場合はこれが真実ではありませんが、私は思っていません – dynamic

+2

Python、JavaScriptまたはPHPで 'eval'の有効なユースケースを見つけるのは難しいと思います。しかし、MATLABについてはわかりませんが、そこではどのコンストラクトが利用できるか分かりません(さらに重要なのは、どのコンストラクトが利用可能でないかです)。 –

+2

@ yes123:これらのような一般化は絶対にしないでください。 –

答えて

5
  1. ここでevalを使用すると、非評価版よりも遅くなる可能性がありますが、コードではボトルネックにはなりません。ただし、パフォーマンスは1つの問題に過ぎません。メンテナンス(デバッグを含む)と可読性は他のものです。
  2. MatlabがJITコンパイラを使用し、eval行を最適化できないため、速度低下が発生します。
  3. 代わりに、代わりに適切なMatlabの機能についての知識が不足しているため、評価の使用がほとんどの場合です。この特定のケースでは、Figureハンドルがfig1からfig4までの変数名に格納されるという問題があります。それらがfigという配列に格納されていた場合、つまりfig(1)など、evalは不要です。

EDITここevalはMatlabのでは避けるべきである理由についてローレンのShureによる2件の優れた記事があります。 Evading evalおよびMore on evalである。

1

ほとんどの場合、文字列を実際のコードに解析する必要があるため、減速が発生します。これは慎重に使用すると大きな問題ではありませんが、コードをループ(明示的なループやJavaScriptのsetInterval()など)して使用すると、パフォーマンスが大幅に低下します。

共通のは、私が良く行うことができるevalのために見てきました使用していますが、次のとおりです。[]表記の無知で

  • アクセスするプロパティ名が代わりに行うことができる引数名に基づいて機能を呼び出す
  • switchvar1ような名前
  • へのアクセス変数、var2、(より安全で、コードインジェクションのリスクを防止する)とvar3彼らはあるべき配列の代わりに

正直言って、問題を解決する唯一の方法がevalという単一の状況に遭遇したことはありません。私はあなたがプログラムの構造に代わるものであること、または最適に動作するように時間を費やす前にプログラムをテストするための一時的な解決策として有用であるという点でgotoに似ていると思います。

+0

私は 'setInterval'を"主要なパフォーマンス低下 "と呼んでいません...間隔の実行、何、速いものの20倍/秒ですか?そして、現代のエンジンは何万何万行ものコードを即座に「解析する」ことができますか? –

5

evalの機能は危険です実際に必要な例はほとんどありません。たとえば、あなたは数字が配列fig(1)にハンドル格納する場合、あなたが与えたコードを簡単に書き換えることができ、fig(2)などと明確である

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

を書き、少ない文字を使用して、MATLABエディターのリンターによって分析することができますあなたがコードを拡張する必要がある場合には、より簡単に変更可能で、奇妙なバグが発生しにくくなります。

実際にあなたが何をしているのか分からない限り(すなわち、複雑なLispマクロを書く場合、または言語のASTを操作するのと同等のものを書いている場合など)は、evalを決して使用しないでください。それが何を意味するのか分かりません、おそらくevalを使う必要はありません)。

同じ結果を達成するために、ほとんど常により明確で、より効率的で危険性の低い方法があります。多くの場合、evalへのコールは、recursionhigher-order functionまたはループの何らかの形式に置き換えることができます。ここで

+0

これは動作しません。'fig1'はFigureハンドルを含む変数です。 'name'は文字列を含む変数です。 – Jonas

+0

良い点 - 'saveas'の構文に慣れていない!私は編集します。 –

+0

OK、-1が消えます:) – Jonas

1

は別の意味合いです:

あなたがevalを使用するプログラムをコンパイルするとき、あなたはいくつかの機能が必要とされているコンパイラに伝えるプラグマを置く必要があります。たとえば:

このコードはコンパイルされ、よく実行します。

foo() 

しかし、この1は、プラグマが追加必要があります。

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

そうでない場合は、実行時に問題が発生します。

関連する問題