66

現在、JavaScript エンジンについて混乱しています。JavaScript をネイティブ コードにコンパイルしたため、 V8が大したことはわかっています。

次に、 Mozilla SpiderMonkeyについて読み始めました。これは、私が理解していることから、C で記述されており、JavaScript をコンパイルできます。では、これは V8 とどう違うのでしょうか? これが本当なら、なぜ Firefox はこれを行わないのでしょうか?

最後に、Rhinoは文字どおり JavaScript を Java バイト コードにコンパイルするので、Java の速度の利点をすべて利用できますか? そうでない場合、デスクトップでスクリプトを作成するときに V8 を実行しないのはなぜですか?

4

4 に答える 4

91

JIT を行う場合でも、JavaScript の実行にはさまざまなアプローチがあります。V8 と Nitro (以前は SquirrelFish Extreme として知られていた) は、メソッド全体の JIT を実行することを選択します。つまり、スクリプトに遭遇すると、すべての JavaScript コードをネイティブ命令にコンパイルし、コンパイルされた C コードであるかのように単純に実行します。SpiderMonkey は代わりに「トレース」JIT を使用します。これは、最初にスクリプトをバイトコードにコンパイルして解釈しますが、ループなどの「ホット スポット」を探して実行を監視します。1 つを検出すると、そのホット パスだけをマシン コードにコンパイルし、後でそれを実行します。

どちらのアプローチにも長所と短所があります。全メソッド JIT は、実行されるすべての JavaScript がマシン コードとしてコンパイルおよび実行され、解釈されないことを保証します。これは一般に高速です。ただし、実装によっては、決して実行されない、または 1 回しか実行されず、パフォーマンスが重要ではないコードのコンパイルにエンジンが時間を費やすことを意味する場合があります。さらに、このコンパイル済みコードはメモリに格納する必要があるため、メモリ使用量が増加する可能性があります。

SpiderMonkey に実装されているトレース JIT は、メソッド全体の JIT と比較して非常に特殊化されたコードを生成できます。これは、既にコードが実行されており、変数の型を推測できるためです (for ループ内のインデックス変数をネイティブ整数として扱うなど)。 )、ここで、JavaScript は型指定されておらず、型が変更される可能性があるため、メソッド全体の JIT は変数をオブジェクトとして扱う必要があります (仮定が失敗した場合、SpiderMonkey は単純にトレースを「終了」し、バイトコードの解釈に戻ります)。ただし、現在、SpiderMonkey のトレース JIT は、トレースが単一の実行パスに最適化されているため、多数の分岐があるコードでは効率的に機能しません。さらに、トレースをコンパイルすることを決定する前に実行を監視し、そのトレースに実行を切り替えると、オーバーヘッドが発生します。また、

于 2010-01-27T13:57:39.717 に答える
17

V8 は、すべての JS をマシン コードにコンパイルするため、最速です。

SpiderMonkey (FF が使用するもの) も高速ですが、マシン コードではなく中間バイトコードにコンパイルされます。それがV8との大きな違いです。編集 - 新しい Firefox リリースには、SpideMonkey の新しいバリアントが付属しています。トレースモンキー。TraceMonkey は、重要な部分の JIT コンパイルを行い、おそらく他のスマートな最適化を行います。

Rhino は Javascript を Java クラスにコンパイルするため、基本的に Javascript で「Java」アプリケーションを作成できます。Rhino は、バックエンドで JS を解釈して操作する方法としても使用され、リフレクションなどの完全なコード理解を備えています。これは、YUI Compressor などで使用されます。

あちこちで V8 の代わりに Rhino が使用されている理由は、おそらく V8 が比較的新しいためです。そのため、多くのプロジェクトが、たとえば Yahoo ウィジェットなど、すでに Rhino/Spidermonkey を JS エンジンとして使用しています。(「デスクトップ上のスクリプト」で言及しているものだと思います)

編集 - このリンクは、SpiderMonkey が非常に広く採用されている理由についての洞察も与えるかもしれません。 アプリケーションに組み込む Javascript エンジンはどれですか?

于 2010-01-26T03:40:21.213 に答える
5

さまざまなブラウザー内 Javascript エンジンがどのように積み重なっていくかを確認したい場合は、Safari 4 (はい、Windows でも動作します!)、Chrome V8、Firefox 3.5、および IE 8 (Windows を使用している場合) をインストールして、ベンチマークを実行してください。 :

http://www2.webkit.org/perf/sunspider-0.9/sunspider.html

上記で Pointy が言ったように、新しい Firefox 3.5 は TraceMonkey を使用し、何らかの形式の JIT を使用してオンザフライでコードを中間編集するようにコンパイルします。したがって、V8に比べてやや有利になるはずです。少なくとも、Firefox 3 SpiderMonkey (JIT なし) のように V8 よりも 10 倍遅くなることはありません。

私にとっては... Safari 4.0.3 は、Win XP の Firefox 3.5.3 で Tracemonky よりも 2.5 倍高速でした。IE8 ははるかに遅かった。現在、Chrome をインストールしていません。

Java バイトコードにコンパイルする Rhino については知りません。実行時にオブジェクト インスタンスに属性を追加できるなど、Javascript の動的機能をまだ解釈している場合 (Javascript で許可されている obj.someNewAttribute="someValue" の例)... 完全に「コンパイル済み」であるかどうかはわかりません。 " をバイトコードに変換すると、Javascript を実行するたびに Javascript ソース コード テキストからコンパイルする必要がないこと以外に、パフォーマンスが向上しない可能性があります。Javascript では、eval("x=10;y=20;z=x*y"); のような非常に動的な構文が使用できることに注意してください。つまり、実行時にコンパイルされるコードの文字列を構築できます。そのため、JVM バイトコードにコンパイルしたとしても、Rhino は混合モードで解釈/コンパイルされると思います。

JVM は、JIT をサポートする非常に優れたものではありますが、依然としてインタープリターです。したがって、Rhino-on-JVM を 2 つのインタープリター レイヤー (インタープリター オン インタープリター) またはインタープリター^2 と考えるのが好きです。一方、他の Javascript エンジンのほとんどは C で記述されているため、インタープリターのように動作する必要があります^1。各インタープリター レイヤーは、C や C++ (たとえば、Perl、Python、Ruby を参照) と比較して 5 ~ 10 倍のパフォーマンス低下を追加する可能性がありますが、JIT を使用すると、パフォーマンス ヒットは 2 ~ 4 倍のオーダーではるかに低くなる可能性があります。そして、JVM はこれまでで最も堅牢で成熟した JIT エンジンの 1 つを備えています。

したがって、走行距離は間違いなく異なり、独自のハードウェアと OS で意図したアプリケーションの本当の答えが必要な場合は、いくつかの本格的なベンチマークを実行することでおそらく恩恵を受けるでしょう.

多くの人がRhinoを使用していることを知っているので、Rhinoが極端に遅くなることはありません。主な魅力は速度ではなく、Java ライブラリへのフックを備えた、コーディングが容易で軽量で組み込み可能なインタープリターであるため、ソフトウェア プロジェクトのスクリプト作成/構成/拡張性に最適です。UltraEdit などの一部のテキスト エディタには、代わりのマクロ スクリプト エンジンとして Javascript が組み込まれています。すべてのプログラマーは、JavaScript を非常に簡単に習得できるように思われるため、簡単に習得できます。

Rhino の利点の 1 つは、JVM が実行されるほぼすべての場所で実行できることです。私の経験では、スタンドアロンの TraceMonkey または SpiderMonkey をビルドしてコマンド ラインから実行しようとすると、Windows などのシステムでは少し面倒です。また、独自のアプリケーションに組み込むにはさらに時間がかかる場合があります。しかし、組み込み可能な言語を使用することの見返りは、大きなプロジェクトにとっては価値があります。これは、それが目的である場合に「独自の」ミニ スクリプト ソリューションを作成する必要がある場合と比較してです。

Java と rhino jar があれば、Rhino でのスクリプティングは非常に簡単です。JavaScript を記述して、コマンド ラインから実行するだけです。単純な作業にいつも使用しています。

于 2010-01-26T04:51:42.993 に答える
3

質問に答えるには、なぜネイティブコードとバイトコードなのか...

ネイティブ コードはより高速であり、Google にとっては戦略的な選択です。少なくともその 1 つが ChromeOS である JS を計画しているためです。

この質問に関する優れたビデオが Channel9 に投稿されており、V8 の背後にいる人物である Lars Bak とのインタビューがここにあります。

于 2010-01-26T03:47:45.003 に答える