0

次の 2 つが与えられます。

シナリオ 1

function inner() {
  // a bunch of code that does stuff
}
function outer() {
  inner();
}
for(var i = 0; i < 10000; i++) {
  outer();
}

シナリオ 2

function outer() {
  function inner() {
    // a bunch of code that does stuff
  }
  inner();
}
for(var i = 0; i < 10000; i++) {
  outer();
}

どちらの場合も動作は同じです。間違いありません。しかし、フードの下の違いは何ですか? シナリオ 2 でインタプリタが実行している余分な作業があれば、どれくらいですか? メモリに影響がありますか。あるいは、たとえば の胴体inner()が長くなると、パフォーマンスへの影響が大きくなりますか?

私の質問は実際的な問題に関するものではないので、「なぜそれをしたいのですか」とわざわざ尋ねないでください。JS 関数がどのように解析され、表現されるかをより深く理解しようとしています。ありがとう!

4

2 に答える 2

1

多くのエンジンがあります:http://en.wikipedia.org/wiki/List_of_ECMAScript_engines

それらのいくつかはJITコンパイルであるため、実行時に解釈する他のものよりも高速です。パフォーマンスの低下は、JITコンパイラー(inner一度コンパイルして再利用)では無視できますが、インタープリター(inner何度も解釈する)では明らかです。inner体が成長するとより明白になります。

于 2012-11-08T00:45:34.330 に答える
1

しかし、フードの下の違いは何ですか? シナリオ 2 でインタプリタが実行している余分な作業があれば、どれくらいですか?

JavaScript エンジンに完全に依存します。(それらの多くは実際にオンザフライでコンパイルされるため、私はそれらを「インタープリター」とは呼びません。)

理論的innerには、エンジンはに入るたびに再解釈/再コンパイルする可能性がありouterます。または、少なくとも、innerへの呼び出しごとに新しいを割り当てouterます。

最新のエンジンでは、コードinner1 回だけコンパイルされて再利用され、呼び出しごとに新しい関数オブジェクトが作成され、outerそのコードが別の実行コンテキストで再利用される可能性が高くなります。これによる影響はごくわずかです ({}オブジェクトの作成による影響を気にせずに JavaScript 関数を記述する頻度を考慮してください)。確かにそれはほとんどの状況で V8 (Chrome のエンジン) が行うことであり、ほとんどの最新のエンジンが行うことはほぼ確実です。

于 2012-11-08T00:10:58.260 に答える