web-dev-qa-db-fra.com

Avantages des moteurs Javascript

Je suis confus à propos des moteurs JavaScript en ce moment. Je sais que V8 était un gros problème car il compilait JavaScript en code natif.

Ensuite, 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 fait-il pas cela?

Enfin, Rhino compile-t-il littéralement le code JavaScript en Java code d'octet pour que vous obteniez tous les avantages de vitesse de Java? Sinon, pourquoi les gens n'exécutent-ils pas V8 lors de l'écriture des scripts sur leur bureau?

58
Jan

Il existe différentes approches pour l'exécution de JavaScript, même lors de l'exécution de JIT. V8 et Nitro (anciennement SquirrelFish Extreme) choisissent de faire un JIT complet, ce qui signifie qu'ils compilent tout le code JavaScript en instructions natives lorsqu'ils rencontrent un script, puis exécutent simplement cela comme s'il s'agissait d'un code C compilé. SpiderMonkey utilise à la place un JIT de "traçage", qui compile d'abord le script pour le bytecode et l'interprète, mais surveille l'exécution, recherchant des "points chauds" tels que des boucles. Lorsqu'il en détecte un, il compile alors uniquement ce chemin d'accès direct au code machine et l'exécute à l'avenir.

Les deux approches ont des avantages et des inconvénients. JIT à 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 devrait en général être plus rapide. Cependant, selon 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 en termes de performances. De plus, ce code compilé doit être stocké en mémoire, ce qui peut entraîner une utilisation accrue de la mémoire.

Le JIT de traçage tel qu'implémenté dans SpiderMonkey peut produire du code extrêmement spécialisé par rapport à un JIT de méthode complète, car 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 peut changer (SpiderMonkey va simplement "tomber" la trace si l'hypothèse échoue et retourner à l'interprétation du bytecode). Cependant, le traçage JIT de SpiderMonkey ne fonctionne actuellement pas efficacement sur le code avec de nombreuses branches, car les traces sont optimisées pour des chemins d'exécution uniques. En outre, 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 basculer l'exécution sur cette trace. De plus, si le traceur fait une hypothèse qui est par la suite violée (comme un type de changement de variable), le coût de la suppression de la trace et du retour à l'interprétation est probablement plus élevé qu'avec un JIT complet.

79
Ted Mielczarek

La V8 est la plus rapide, car elle compile tous les JS en code machine.

SpiderMonkey (ce que FF utilise) est également rapide, mais se compile en un code d'octet intermédiaire, pas un code machine. C'est la principale différence avec le V8. EDIT - Les versions plus récentes de Firefox sont livrées avec une variante plus récente de SpideMonkey; TraceMonkey. TraceMonkey effectue la compilation JIT des pièces critiques et peut-être d'autres optimisations intelligentes.

Rhino compile Javascript en classes Java, vous permettant ainsi d'écrire essentiellement 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 du code complet compréhension, comme la réflexion, utilisée par exemple par le compresseur YUI.

La raison pour laquelle Rhino est utilisé au lieu de V8 partout 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 à cela que vous faites référence avec des "scripts sur leur bureau")

edit- Ce lien pourrait également donner un aperçu de la raison pour laquelle SpiderMonkey est si largement adopté. Quel moteur Javascript intégreriez-vous dans votre application?

12
adamJLev

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

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

Je crois que comme Pointy l'a dit ci-dessus, le nouveau Firefox 3.5 utilise TraceMonkey qui compile également pour interméditer du code à la volée en utilisant une forme de JIT. Il devrait donc se comparer assez favorablement au V8. Au moins, il ne sera pas 10 fois plus lent que V8 comme Firefox 3 SpiderMonkey (sans JIT).

Pour moi ... safari 4.0.3 était 2,5 fois plus rapide que Tracemonky dans Firefox 3.5.3 sur Win XP. IE8 était beaucoup plus lent. Je n'ai pas Chrome installé pour le moment.

Je ne sais pas si Rhino se compile en Java bytecode. S'il continue d'interpréter les fonctionnalités dynamiques de Javascript telles que la possibilité d'ajouter des attributs aux instances d'objets au moment de l'exécution (exemple obj.someNewAttribute = "someValue" ce qui est autorisé en Javascript) ... Je ne suis pas sûr qu'il soit entièrement "compilé" en bytecode, et vous pourriez ne pas obtenir de meilleures performances autres que vous n'avez pas à compiler à partir du texte du code source Javascript à chaque fois que votre Javascript N'oubliez pas que Javascript autorise 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 qui seront compilées au moment de l'exécution. C'est pourquoi je pense que Rhino serait interprété/compilé en mode mixte même si vous avez compilé en bytecode JVM.

La JVM est toujours un interprète, quoique très bon avec le support JIT. J'aime donc penser à Rhino-on-JVM comme 2 couches d'interpréteur (interprète-sur-interprète) ou interprète ^ 2. Alors que la plupart de vos autres moteurs Javascript sont écrits en C, et en tant que tels devraient fonctionner plus comme l'interpréteur ^ 1. Chaque couche interpréteur peut ajouter une dégradation des performances de 5 à 10 fois par rapport à C ou C++ (réf Perl ou Python ou Ruby par exemple), mais avec JIT les performances la frappe peut être beaucoup plus faible de l'ordre de 2 à 4 fois. Et la JVM possède l'un des moteurs JIT les plus robustes et les plus matures jamais créés.

Donc, votre kilométrage variera certainement et vous bénéficierez probablement de faire des repères sérieux si vous voulez une vraie réponse pour votre application prévue sur votre propre matériel et système d'exploitation.

Rhino ne peut pas être trop lent, car je sais que beaucoup de gens l'utilisent. Je pense que son attrait principal n'est pas sa vitesse, mais le fait qu'il est facile à coder/léger/intégrable/interprète qui a des crochets dans les bibliothèques Java, ce qui le rend parfait pour les scripts/configuration/extensibilité de votre projet logiciel. Certains éditeurs de texte comme UltraEdit intègrent même Javascript en tant que moteur de script de macro alternatif. Chaque programmeur semble être capable de trébucher sur javascript assez facilement, il est donc facile de le reprendre également.

Un avantage de Rhino est qu'il s'exécute à peu près partout où s'exécute la JVM. D'après mon expérience, essayer d'obtenir TraceMonkey ou SpiderMonkey autonome pour construire et exécuter à partir de la ligne de commande peut être un peu pénible 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 en vaudrait la peine pour un gros projet, par rapport à la nécessité de "lancer votre propre" mini solution de script si c'est ce que vous cherchez à faire.

Les scripts avec Rhino sont vraiment faciles si vous avez Java et le pot rhino, vous écrivez simplement votre javascript et vous l'exécutez à partir de la ligne de commande. Je l'utilise tout le temps pour des tâches simples.

6
linguanerd

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

Le code natif est plus rapide et pour google un choix stratégique car ils ont prévu de JS l'un d'eux au moins est ChromeOS.

Une bonne vidéo sur cette question est publiée sur Channel9 avec une interview de Lars Bak, l'homme derrière V8 peut être trouvé ici

3
Zied