Comment fonctionne le Chrome V8? Et pourquoi JavaScript n'a-t-il pas été compilé en JIT en premier lieu?


19

J'ai fait des recherches sur les interprètes / compilateurs, puis je suis tombé sur JIT-Compilation - en particulier le moteur Javascript V8 de Google Chrome.

Ma question est -

  1. Comment peut-il être plus rapide que l'interprétation standard?
  2. Pourquoi n'a pas été JIT Compilation utilisé en premier lieu?


Ma compréhension actuelle

  1. Chaque programme Javascript commence en tant que code source , puis, quelle que soit la méthode d'exécution, est finalement traduit en code machine .
    La compilation JIT et l' interprétation doivent suivre ce chemin, alors comment la compilation JIT peut-elle être plus rapide (également parce que JIT est limité dans le temps, contrairement à la compilation AOT)?

  2. Il semble que JIT-compilation est une innovation relativement ancien , basé sur de Wikipédia JIT Compilation article .

« Le compilateur JIT publiés plus tôt est généralement attribuée à travailler sur LISP par McCarthy 1960 ».

"Smalltalk (c. 1983 ) a ouvert la voie à de nouveaux aspects des compilations JIT. Par exemple, la traduction en code machine a été effectuée à la demande, et le résultat a été mis en cache pour une utilisation ultérieure. Lorsque la mémoire devenait rare, le système supprimait une partie de ce code et régénérait quand il était à nouveau nécessaire. "

Alors pourquoi Javascript a-t-il été interprété pour commencer ?


Je suis très confus et j'ai fait beaucoup de recherches à ce sujet, mais je n'ai pas trouvé de réponses satisfaisantes.

Des réponses si claires et concises seraient appréciées. Et si des explications supplémentaires sur les interprètes, les compilateurs JIT, etc. doivent être apportées, cela est également apprécié.


2
# 2 et # 3 sont responsables, mais "Comment fonctionne le moteur Chrome V8?" sans aucune qualification est beaucoup trop large; la seule bonne réponse est un lien vers le code source de V8. Est-ce que vous l' intention de demander quelque chose de plus précis sur V8? (sinon il serait préférable de supprimer cette partie de la question)
Ixrec

Le deuxième coup d' œil, le seul point de me demander n ° 1 était de comprendre n ° 2, donc je vais l' enlever. Merci pour la contribution.
Anton Paras

Ceci n'est pas mentionné dans les autres réponses mais la compilation JIT est difficile. Il est pas une chose facile à faire parce que les erreurs résultant de résultat de la compilation JIT à des erreurs de segmentation à la place d'erreurs - le programme se bloque au lieu de jeter une erreur dans la console. Oui, pour un programmeur compétent de C à l' aise avec gdb ce ne sont pas un problème. Mais presque tous les programmeurs C compétents à l'aise avec gdb sont payés pour travailler sur d'autres projets. Certaines autres langues comme Perl et Ruby n'ont toujours pas d'interprètes JIT traditionnels.
slebetman

Au cas où vous vous poseriez la question . Je parle de ce du point de vue d'un développeur noyau / Conception d'un langage de programmation. Pendant quelques années, j'ai été embauché pour maintenir le langage de programmation Ferite. L'une des listes de souhaits que nous avions était de mettre en œuvre une ECE. Cela n'est jamais arrivé - nous avons déménagé pour aller à la place. PHP a récemment obtenu un compilateur JIT (HVVM) grâce à Facebook verser suffisamment d' argent pour y arriver.
slebetman

Réponses:


43

La réponse courte est que JIT a des temps d'initialisation plus longs, mais est beaucoup plus rapide à long terme, et JavaScript n'était pas initialement prévu pour le long terme.

Dans les années 90, JavaScript typique sur un site Web reviendrait à une ou deux fonctions dans l' en- tête, et une poignée d' un code embarqué dans les onclickpropriétés et les autres. Il était généralement exécuté correctement lorsque l'utilisateur s'attendait à un énorme délai de chargement de la page de toute façon. Pensez à la validation du formulaire très de base ou les services publics de mathématiques petits comme les calculatrices d'intérêt hypothécaires.

L'interprétation en fonction des besoins est beaucoup plus simple et offre un rendement tout à fait convenable pour les cas d'utilisation de la journée. Si vous vouliez quelque chose avec des performances à long terme, vous utilisiez flash ou une applet java.

Google Maps en 2004 a été l'une des premières applications tueuses pour une utilisation intensive de JavaScript. Il a ouvert les yeux sur les possibilités de JavaScript, mais a également mis en évidence ses problèmes de performances. Google a passé un certain temps à encourager les navigateurs à améliorer leurs performances JavaScript, puis a finalement décidé que la concurrence serait le meilleur facteur de motivation et leur donnerait également la meilleure place à la table des normes de navigateur. Chrome et V8 ont été libérés en 2008 à la suite. Maintenant, 11 ans après Google Maps est venu sur les lieux, nous avons de nouveaux développeurs qui ne me souvienne pas JavaScript étant jugée insuffisante pour ce genre de tâche.

Disons que vous avez une fonction animateDraggedMap. L'interprétation peut prendre 500 ms et 700 ms pour le compiler. Cependant, après la compilation JIT, l'exécution de 100 ms peut ne prendre que 100 ms. Si ce sont les années 90 et que vous ne vous appelez une fonction une fois , puis de recharger la page, juste à temps ne vaut pas du tout. Si elle est aujourd'hui et que vous appelez des animateDraggedMapcentaines , voire des milliers de fois, que les 200 ms supplémentaires lors de l' initialisation est rien, et il peut être fait dans les coulisses avant que l'utilisateur tente même de faire glisser la carte.


2

En comprenant ce qui se passe lors de l'exécution, il est possible d'apporter des modifications au code ou à l'interprétation du code qui permettent de l'exécuter plus rapidement ou de le compiler mieux que ce qui est connu à l'avance.

On peut en dire beaucoup à ce sujet - il fait l’objet de nombreuses recherches. Ma propre explication ici que j'ai commencé à écrire pâle en comparaison avec la réponse donnée dans Comprendre les différences: interprète traditionnel, compilateur JIT, interprète JIT et compilateur AOT


Tout simplement, JavaScript n'a pas été initialement compilé ou examiné pour JIT car il n'a jamais été conçu pour être quelque chose d'aussi complexe ou important.

L'intention initiale de Java Script était de lien vers applets Java sur une page Web. La possibilité de cliquer sur un bouton ou d'entrer une valeur dans un champ de formulaire, puis de travailler dans une méthode d'applet Java peut être vue dans Invocation de méthodes d'applet à partir du code JavaScript . Il était également possible, via JavaScript, d'aller dans l'autre sens pour invoquer du code JavaScript à partir d'une applet .

l'intention initiale JavaScript était applets lien et les pages html qui les contenaient. Pour une petite tâche, on n'a pas besoin d'excellentes performances (si vous voulez des performances, appelez la méthode applet lequel est JIT'ed).

Ce ne fut qu'après Netscape commença à travailler important avec JavaScript de sa langue nationale et promouvoir le développement (dont le serveur Side JavaScript dans Netscape Enterprise Server - dont, soit dit en passant a fait avant la compilation de temps) que Le JavaScript est entré en lumière un objectif sérieux . Il a fallu plusieurs années après que les outils nécessaires pour le rendre utile.


1
Non, Javascript n'est pas lié à Java. Et applets Java sont bytecode JVM.
Basile STARYNKEVITCH

@BasileStarynkevitch Le JavaScript a été conçu pour fonctionner avec les applets Java dans les pages Hameau - agissant de ciment entre les DOM HTML et les méthodes contenues dans les objets Java. Il n'est pas et n'a jamais été conçu pour être Java.

JavaScript était à l'origine appelé ECMAScript (ou quelque chose comme ça) et n'avait rien à voir avec Java. Comment il est arrivé à être Le JavaScript appelé fait l'objet de la recherche indépendante pour les personnes intéressées. Cela a semé la confusion de plus en plus.
quick_now

1
@quickly_now et est toujours tc39.github.io/ecma262
caub

Oui. Et pour une raison étrange, quand j'ai souligné que ci-dessus, j'ai été déçu pour cela!
quick_now

1

JIT est rapide pour JavaScript, parce qu'il est impossible générer un code machine rapide lorsque vous ne connaissez pas le type de vos variables.

Lorsque vous ne disposez pas d'informations de type, les calculs sont coûteux. Par exemple,

x + y

est assez compliqué si vous ne savez rien sur x et y. Ils pourraient être des entiers, doubles, des chaînes ou des objets même si ce calcul a des effets secondaires. Étant donné que nous ne disposons pas typage statique, c'est un calcul coûteux.

Avec la compilation juste à temps, nous pouvons utiliser l' information d'exécution et en faire un calcul plus rapide. Lors de l' exécution, V8 assure le suivi du type de variables. Si le code ci-dessus est exécuté plusieurs fois avec, par exemple, des chaînes, le compilateur peut exécuter les instructions beaucoup plus simples pour la concaténation de chaînes. Ainsi , lorsque le cours du compilateur x + y, au lieu de courir beaucoup de code qui se ramifie pour plusieurs types de x et y, le compilateur rapidement vérifie si nous avons des chaînes à nouveau, puis exécute seulement quelques lignes de code machine que les chaînes spécifiquement concaténation.

En exemple, C ++ le compilateur connaît les types de x et avance y de temps, car nous avons dû déclarer les variables. Ainsi, il peut générer optimisé code machine pour la concaténation des chaînes avant même l'exécution du code.


0

1) Comment peut-il être plus rapide que l'interprétation standard? Eh bien, un exemple pensé serait le suivant; supposons que nous avons 2 applications ApplicationCompiled et ApplicationInterpreted. Ces deux programmes font exactement la même chose, et partagent le même code source. ApplicationCompiled prend 6 secondes à compiler.

Disons que le timing du scénario A est:

  • Pour ApplicationCompiled: 4 secondes
  • Pour l'applicationInterprétée: 12 secondes

Donc, au total ApplicationCompiled en 10 secondes pour exécuter Scénario A (compilation 6 secondes, 4 secondes en cours d'exécution) et ApplicationInterpreted dure 12 secondes au total, à l'exécution. Je ne suis pas un exemple spécifique pour vous montrer, et je ne sais pas dans quels cas ce qui précède serait vrai - elle dépend aussi fortement de la intelligence interpret et compilateur sont.

Il est évident que cela est très simplifié, mais IMHO la même idée peut être appliqué à JIT compiler / interpréter. La question suivante serait alors « comment déterminer - avec low cost - si cette succursale doit être JIT compilé ou interprété »? Je suis hors de ma ligue ici :)

2) pourquoi n'a pas JIT Compilation utilisé , en premier lieu? Je ne sais pas, je recon il est tout simplement une question de ressources et de la maturité des progrès disponibles dans la fabrication d' un langage difficile à optimiser , comme utiliser des techniques de JavaScript avances telles que celles - ci. Il y avait probablement beaucoup de fruits suspendus plus bas à l'époque.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.