2010-01-26 21 views
50

Je suis confus au sujet des moteurs de Javascript en ce moment. Je sais que V8 était un gros problème car il compilé JavaScript en code natif.Javascript Engines Avantages

Puis j'ai commencé à lire sur Mozilla SpiderMonkey, qui d'après ce que je comprends est écrit en C et peut compiler JavaScript. Alors, comment est-ce différent de V8 et si cela est vrai, pourquoi Firefox ne le fait pas?

Enfin, est-ce que Rhino compile littéralement le code JavaScript en octets Java pour que vous bénéficiez de tous les avantages de vitesse de Java? Si non, pourquoi les gens n'exécutent pas V8 lorsqu'ils écrivent des scripts sur leur bureau?

+1

Rhino peut être compilé en code octet Java. https://developer.mozilla.org/en/Rhino_JavaScript_Compiler – Thilo

Répondre

8

V8 est le plus rapide, car il compile tous les JS en code machine.

SpiderMonkey (ce que FF utilise) est rapide aussi, mais compile à un octet-code intermédiaire, pas à un code machine. C'est la différence majeure avec V8. EDIT - Les nouvelles versions de Firefox sont livrées avec une nouvelle version de SpideMonkey; TraceMonkey. TraceMonkey fait la compilation JIT des parties critiques, et peut-être d'autres optimisations intelligentes. Rhino compile Javascript en classes Java, vous permettant ainsi d'écrire des applications "Java" en Javascript. Rhino est également utilisé comme un moyen d'interpréter JS dans le backend et de le manipuler, et d'avoir une compréhension complète du code, comme la réflexion. Ceci est utilisé par exemple par le compresseur YUI. La raison pour laquelle Rhino est utilisé à la place de V8 est probablement parce que V8 est relativement nouveau, donc beaucoup de projets ont déjà utilisé Rhino/Spidermonkey comme moteur JS, par exemple les widgets Yahoo. (Je suppose que c'est ce dont vous parlez avec des "scripts sur leurs ordinateurs de bureau")

edit- Ce lien pourrait également donner un aperçu de la raison pour laquelle SpiderMonkey est si largement adopté. Which Javascript engine would you embed in your application?

+2

Umm TraceMonkey fait aussi la traduction de JIT au code machine ... Aussi je ne pense pas que ce soit précis de dire que V8 "compile" le JavaScript au code machine - C'est plus ou moins le même type d'approche JIT que TraceMonkey. – Pointy

+0

@Pointy, La différence AFAIK entre TraceMonkey et V8 est que TraceMonkey se compile en code intermédiaire, dont certains compilent JIT en code machine lors de son exécution. V8 compile tout directement au code machine. –

+1

"V8 compile le code source JavaScript directement dans le code machine lors de sa première exécution Il n'y a pas de code octet intermédiaire, pas d'interpréteur." Source: http://code.google.com/apis/v8/design.html Donc, fondamentalement, la compilation comme un compilateur C ferait l'affaire. En outre, V8 compile tous JS, et TraceMonkey fait JIT – adamJLev

3

Pour répondre à la question, pourquoi le code natif Vs code Byte ...

Le code natif est plus rapide et pour Google un choix stratégique parce qu'ils ont un plan pour JS d'entre eux au moins est ChromeOS.

Une bonne vidéo sur cette question est affichée sur Channel9 avec une interview avec Lars Bak l'homme derrière V8 se trouve here

6

Si vous voulez voir comment les différents dans le navigateur moteurs Javascript empilent, installez Safari 4 (oui, il fonctionne sur windows maintenant aussi!), Chrome V8, Firefox 3.5 et IE 8 (si vous êtes sur windows) et exécutez le benchmark:

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

Je crois que dit Pointy ci-dessus, la new Firefox 3.5 utilise TraceMonkey qui compile aussi pour interméditer le code à la volée en utilisant quelques f orm de JIT. Donc, il devrait comparer à V8 assez favorablement. Au moins, il ne sera pas 10x plus lent que V8 comme Firefox 3 SpiderMonkey (sans JIT) était. Pour moi ... safari 4.0.3 était 2.5x plus rapide que Tracemonky dans Firefox 3.5.3 sur Win XP. IE8 était beaucoup plus lent. Je n'ai pas installé Chrome pour le moment.

Je ne connais pas la compilation de Rhino en bytecode java. S'il interprète toujours les caractéristiques dynamiques de Javascript, par exemple en ajoutant des attributs aux instances d'objets lors de l'exécution (exemple obj.someNewAttribute = "someValue" qui est autorisé en Javascript) ...Je ne suis pas sûr qu'il soit entièrement "compilé" en bytecode, et vous n'obtiendrez peut-être pas de meilleures performances si ce n'est que vous n'avez pas besoin de compiler du code source Javascript chaque fois que votre Javascript fonctionne. Rappelez-vous que Javascript permet une syntaxe très dynamique telle que eval ("x = 10; y = 20; z = x * y"); ce qui signifie que vous pouvez créer des chaînes de code compilées lors de l'exécution. C'est pourquoi je pense que Rhino serait en mode mixte interprété/compilé même si vous compiliez en JVM bytecode.

La JVM est toujours un interpréteur, mais très bon avec le support JIT. J'aime donc penser à Rhino-on-JVM comme 2 couches interpréteur (interprète sur interpréteur) ou interprète^2. Alors que la plupart de vos autres moteurs Javascript sont écrits en C, et en tant que tel devrait ressembler plus à l'interpréteur^1. Chaque couche d'interpréteur peut ajouter 5 à 10 fois plus de dégradation que C ou C++ (ref Perl ou Python ou Ruby par exemple), mais avec JIT, la performance peut être beaucoup plus faible de l'ordre de 2-4x. Et la JVM possède l'un des moteurs JIT les plus robustes de tous les temps.

Donc, votre kilométrage va certainement varier et vous pourriez probablement bénéficier de quelques benchmarks sérieux si vous voulez une vraie réponse pour votre application prévue sur votre propre matériel & OS. Rhino ne peut pas être trop terriblement lent, car je sais que beaucoup de gens l'utilisent. Je pense que son principal attrait n'est pas sa rapidité, mais le fait qu'il soit facile à coder/léger/embarqué/interpréteur qui a des liens dans les bibliothèques Java, ce qui le rend parfait pour le script/configuration/extensibilité de votre projet logiciel. Certains éditeurs de texte comme UltraEdit intègrent même Javascript comme moteur alternatif de script de macro. Chaque programmeur semble être capable de trébucher facilement via javascript, il est donc facile de le récupérer. Un des avantages de Rhino est qu'il s'exécute à peu près partout où la JVM s'exécute. Dans mon expérience, essayer de faire fonctionner TraceMonkey ou SpiderMonkey en mode autonome pour construire & depuis la ligne de commande peut être un peu douloureux sur des systèmes comme Windows. Et l'intégration dans votre propre application peut prendre encore plus de temps. Mais le retour sur investissement d'un langage intégrable vaudra la peine pour un gros projet, comparé au fait d'avoir à faire «rouler sa propre» mini-solution de script si c'est ce que vous cherchez à faire.

Il est très facile de créer des scripts avec Rhino si vous avez Java et le pot de rhinocéros, il vous suffit d'écrire votre javascript et de l'exécuter à partir de la ligne de commande. Je l'utilise tout le temps pour des tâches simples.

+0

J'ai installé chrome 4 sur ma machine XP, et il fonctionne les benchmarks sunspider environ 3 fois plus vite que Firefox 3.5.3 Tracemonkey. Également découvert que V8 est agréablement facile à télécharger et à construire par rapport à mon expérience précédente avec SpiderMonkey. Bien sûr, vous avez besoin de svn + python 2.4 + scons 1.0.0 + Visual Studio 2005/2008 (l'édition gratuite de VC++ 2008 fonctionne supposément aussi) que j'avais déjà exécutée sur mon PC de développement. Pour être honnête, peut-être que je reviendrai essayer TraceMonkey build pour voir comment il se comporte de nos jours. – linguanerd

+3

Notez que Sunspider n'est pas la seule réponse, c'est juste un benchmark JavaScript (bien que celui que les auteurs de moteurs JavaScript ont fortement optimisé pour). –

+0

VC++ 2008 express (gratuit) fonctionne pour compiler v8 avec scons, l'a fait plus tôt cette semaine. –

73

Il existe différentes approches pour l'exécution de JavaScript, même lorsque vous exécutez JIT. V8 et Nitro (anciennement SquirrelFish Extreme) choisissent de faire un JIT de méthode entière, ce qui signifie qu'ils compilent tout le code JavaScript en instructions natives lorsqu'ils rencontrent un script, puis l'exécutent simplement comme s'il s'agissait d'un code C compilé. SpiderMonkey utilise à la place un JIT de «traçage», qui d'abord compile le script en bytecode et l'interprète, mais surveille l'exécution, à la recherche de «points chauds» tels que des boucles. Quand il en détecte un, il compile juste ce chemin chaud pour le code machine et l'exécute dans le futur.

Les deux approches ont des avantages et des inconvénients. JIT de méthode entière garantit que tout JavaScript exécuté sera compilé et exécuté en tant que code machine et non interprété, ce qui en général devrait être plus rapide. Cependant, en fonction de l'implémentation, cela peut signifier que le moteur passe du temps à compiler du code qui ne sera jamais exécuté, ou ne peut être exécuté qu'une seule fois, et n'est pas critique pour les performances. En outre, ce code compilé doit être stocké en mémoire, ce qui peut entraîner une utilisation plus importante de la mémoire.Le JIT de traçage implémenté dans SpiderMonkey peut produire du code extrêmement spécialisé comparé à un JIT de méthode entière, puisqu'il a déjà exécuté le code et peut spéculer sur les types de variables (comme traiter la variable d'index dans une boucle for). comme un entier natif), où un JIT de méthode entière devrait traiter la variable comme un objet car JavaScript n'est pas typé et le type pourrait changer (SpiderMonkey va simplement "tomber" si l'hypothèse échoue, et retourner à l'interprétation du bytecode) . Cependant, le JIT de traçage de SpiderMonkey ne fonctionne pas actuellement efficacement sur le code avec de nombreuses branches, car les traces sont optimisées pour des chemins d'exécution uniques. De plus, il y a des frais généraux impliqués dans la surveillance de l'exécution avant de décider de compiler une trace, puis de passer l'exécution à cette trace. En outre, si le traceur fait une supposition qui est violée plus tard (comme un type à changement variable), le coût de la perte de trace et du retour à l'interprétation est probablement plus élevé qu'avec une JIT de méthode entière.

+8

Notez que dans les années qui ont suivi, Firefox est passé à l'utilisation d'un JIT de méthode entière ainsi qu'à "JaegerMonkey" et a abandonné le JIT de traçage. –