Quels sont les avantages de juste-à-temps de compilation et avance sur le temps de compilation?
J'ai pensé à ce sujet ces derniers temps, et il me semble que la plupart des avantages accordés aux JIT compilation devrait plus ou moins être attribuée au format intermédiaire au lieu de cela, et que jitting en lui-même n'est pas un bon moyen de générer du code.
De sorte que ces sont les principaux pro-JIT compilation arguments que je l'habitude d'entendre:
- Juste-à-temps de compilation permet une plus grande portabilité. N'est-ce pas imputable au format intermédiaire? Je veux dire, rien ne vous empêche de la compilation de votre virtuel bytecode en natif de bytecode une fois que vous avez sur votre machine. La portabilité est un problème dans la "distribution", de la phase, pas au cours de la 'course' phase.
- Ok, alors que penser de la génération de code à l'exécution? Eh bien, la même chose s'applique. Rien ne vous empêche de l'intégration d'un juste-à-temps compilateur pour un réel juste-à-temps dans votre propre programme.
- Mais le moteur d'exécution compile en code natif, juste une fois, de toute façon, et les magasins de l'exécutable résultant dans une sorte de cache quelque part sur votre disque dur. Oui, bien sûr. Mais il est optimisé votre programme sous des contraintes de temps, et ce n'est pas ce qu'elle soit mieux à partir de là. Voir le paragraphe suivant.
Ce n'est pas comme à l'avance compilation avait pas d'avantages non plus. Juste-à-temps compilation a des contraintes de temps: vous ne pouvez pas garder à l'utilisateur final d'attente à jamais, alors que votre programme se lance, il a donc un compromis à faire quelque part. La plupart du temps ils ont juste optimiser le moins. Un de mes amis avait profilage preuve que les fonctions inline et dérouler les boucles "manuellement" (obscurcissement de code source dans le processus) a eu un impact positif sur la performance de son C# arithmétique programme; faire de même de mon côté, avec mon C programme de remplissage de la même tâche, a abouti à aucun résultat positif, et je crois que c'est due à l'ampleur des transformations mon compilateur été autorisé à faire.
Et pourtant, nous sommes entourés par jitted programmes. C# et Java sont partout, les scripts Python peut compiler en une sorte de pseudo-code binaire, et je suis sûr que tout un tas d'autres langages de programmation en faire de même. Il doit y avoir une bonne raison que je suis absent. Donc, ce qui rend juste-à-temps compilation tellement supérieur à à l'avance compilation?
MODIFIER Pour effacer une certaine confusion, il serait peut-être important de préciser que je suis tout à fait pour une représentation intermédiaire des exécutables. Cela a beaucoup d'avantages (et vraiment, la plupart des arguments pour juste-à-temps compilation sont en fait des arguments pour une représentation intermédiaire). Ma question est au sujet de la façon dont ils devraient être compilé en code natif.
La plupart des moteurs d'exécution (ou de compilateurs pour que ce soit), de préférence, soit la compilation juste-à-temps ou à l'avance. Comme à l'avance compilation apparaît comme une meilleure alternative pour moi parce que le compilateur a plus de temps pour procéder à des optimisations, je me demande pourquoi Microsoft, Sun et tous les autres vont dans l'autre sens. Je suis un peu dubitatif sur le profilage-des optimisations, comme mon expérience avec juste-à-temps programmes compilés affiche pauvres de base des optimisations.
J'ai utilisé un exemple avec du code C seulement parce que j'ai besoin d'un exemple de à l'avance compilation et juste-à-temps compilation. Le fait que C code n'a pas été émis à une représentation intermédiaire est indifférent à la situation, que j'ai juste besoin de montrer que à l'avance compilation peut produire de meilleurs résultats immédiats.
- Je ne suis pas sûr de ce que vous êtes à argumenter. Vous êtes en train de dire que les avantages attribués à JITted code sont vraiment le résultat de la format intermédiaire, et puis vous vous demandez pourquoi ce format intermédiaire est si répandue?
- Non, je ne suis pas plaider contre le format intermédiaire est répandue. Je suis plaidant contre pourquoi il est nécessaire de compiler que le format intermédiaire juste-à-temps au lieu de, disons, à l'avance pendant la phase d'installation.
- Une telle question intéressante. J'ai lu tous les posts et aucun des arguments présentés m'ont convaincu. Je ne comprends toujours pas pourquoi les langues comme Java ne compile le bytecode en code natif à l'avance (il le fera de toute façon en utilisant JIT, alors pourquoi ne pas compiler le code avant, il est exécuté?). Je n'ai jamais vu un code compilé nativement fonctionne plus lentement que d'un code compilé à l'aide de JIT (même après la plus récente étant en cours d'exécution pour semaines) donc les arguments de la "meilleure performance" en faveur de JIT ne font pas de sens pour moi.
- avec un peu plus d'expérience aujourd'hui (cette question est de 3 ans, pouvez-vous le croire?), Je vais mettre davantage l'accent sur le fait que vous n'avez pas besoin de recompiler le bytecode des programmes lorsqu'une classe dans une bibliothèque externe changements. C'est un énorme l'avantage pour les systèmes orientés objet comme Java et le CLR.
- J'ai été relire votre réponse maintenant. En effet, c'est un avantage, mais pas un avantage de performance. Quand j'ai dit que je ne vois pas l'avantage de JIT sur AOT compilation je parle principalement sur la performance. La chose drôle est que Google, avec KitKat 4.4, est en train de tester un AOT compilateur pour Android aussi... donc je suppose qu'il finira par remplace l'actuelle compilateur JIT, quelque chose que j'ai imaginé arriverait tôt ou tard. J'ai vraiment ne peux pas obtenir mon esprit autour de la raison pour laquelle tant de systèmes déménagé à JIT (au lieu de coller à l'AOT) en premier lieu...
- n'ayant pas besoin de recompiler votre programme lorsqu'une bibliothèque changements est un avantage de performance, si l'on considère que cette fonctionnalité est donc crucial, que les applications natives de l'utiliser ainsi, par le déploiement des applications et des bibliothèques séparément, soit lié à l'exécution, ou à être reliés au système d'exploitation fourni bibliothèques. La différence est que JIT code compilé obtient relié à la version de bibliothèque en premier, suivi par l'in-lining et optimisations, avant la version finale du code est exécuté. Cette possibilité n'existe pas pour les applications natives, où chaque fonction de bibliothèque est une boîte noire...
- Ce genre de scénario avec une bibliothèque externe de mise à jour / sw distribution avez-vous en tête? Si l'une des composantes de notre demande de modifications (notre code, bibliothèque de code de dépendance) nous avons besoin de distribuer l'application de mise à jour quand même, non? Je crois que la plupart des mises à jour d'applications sont entraînés par notre code d'application des changements (nouvelles fonctionnalités, des corrections de bug), mais pas de modifications de bibliothèque. Donc, votre argument est plus sur que chaque mise à jour doit la recompilation? Encore une fois, nous ne parlons pas de la phase de développement, en tant que développeur, je suis bien d'utiliser JIT et mise à jour des bibliothèques autant de fois que je veux au cours du développement sans recompilation.
- ne vous recompilez vos applications installées lors de l'installation d'un nouveau codec? Ou lors de la mise à jour de votre pilote graphique? Ce sont des exemples de bibliothèques natives, dont le code n'est jamais incorporé dans le code de l'application. Dans le contexte de Java, l'exemple le plus simple est d'exécuter votre application sur une nouvelle JRE, bénéficiant de corrections de bugs et améliorations de performances. Ou l'abandon de toute nouvelle SPI mise en œuvre dans les env, disent les méthodes de saisie, ImageIO, les jeux de caractères, les systèmes de fichiers, JNDI, auth, JDBC drivers, etc, tous extensible à l'exécution par l'utilisateur sans avoir besoin de le développeur de recompiler...
- Votre codec exemple fait contredit avec votre bibliothèque argument et donne +1 de AOT. Il s'avère que, même si les deux parties de l'app sont sous forme binaire (par exemple .exe et .dll à partir de win), il est possible de mettre à jour l'une d'elle (.dll) sans modifier l'autre. Même s'applique aux JRE, à proprement parler ce juste une autre grande bibliothèque, lorsque de nouvelles JRE vient, nous le recompiler et de lier dynamiquement à partir d'autres déjà compilé apps.
- c'est ce que j'ai déjà dit dans ce commentaire: “cette fonctionnalité est donc crucial, que les applications natives de l'utiliser aussi bien” (reliant les exe et dll), même si le code ne peut pas obtenir inline et optimisé ensemble comme dans un JIT environnement. Ce n'est pas la même chose avec une application Java en tant que “nous” ne pas recompiler lorsque le JRE (ou une bibliothèque), les changements, les JRE ne compiler+optimisez après la liaison, automatiquement.
- donc, votre argument pour le JIT est le genre de traditionnel d'un sujet d'exécution de l'optimisation. Vous dites que la performance de "JIT frais généraux + inline code de bibliothèque" est mieux que "l'AOT + appel de la bibliothèque de code". Est-ce correct?
- c'est plutôt que vous n'avez pas à faire un compromis entre le système cible est la modularité et la performance. En outre, il est plus que “inline code de bibliothèque”, comme l'inlining est seulement le point de départ pour tous les autres optimisations effectuées sur le code combiné. Cependant, je ne dis pas que “JIT frais généraux + JIT avantage” est toujours mieux que de les AOT. AOT nécessite soigneusement choisi des compromis entre la modularisation et de la performance, aussi, en intégrant les données de profilage pour l'optimisation des hot les chemins de code nécessite des efforts supplémentaires (plus qu'on ne fait pas). Mais si c'est bien fait, AOT de chances de victoires.
Vous devez vous connecter pour publier un commentaire.
Une plus grande portabilité: L'
livrable (byte-code) séjours
portable
Dans le même temps, de plus en plus une plate-forme spécifique: Parce que le
JIT-compilation a lieu sur le
même système que le code s'exécute, il
peut être très, très affiné pour
ce système particulier. Si vous ne
avance sur le temps de compilation (et encore
souhaitez expédier le même paquet
tout le monde), vous avez à faire des compromis.
Des améliorations dans la technologie de compilation peuvent avoir un impact sur
les programmes existants. Un meilleur C
compilateur ne vous aide pas du tout
avec des programmes déjà en place. Un
mieux JIT-compilateur va améliorer la
rendement des programmes existants.
Le code Java que vous avez écrit il y a dix ans sera exécuté plus rapidement aujourd'hui.
Adaptation au moment de l'exécution des mesures. Un JIT-compilateur ne peut pas seulement regarder
le code et le système cible, mais
aussi la manière dont le code est utilisé. Il peut
instrument le code en cours d'exécution, et
prendre des décisions sur la façon d'optimiser
selon, par exemple, ce
les valeurs des paramètres de la méthode habituellement
arriver à avoir.
Vous avez raison, JIT ajoute aux coûts de démarrage, et il est donc temps de contrainte pour elle,
alors que l'avance de temps de compilation peut prendre tout le temps qu'il veut. De ce fait, il
plus approprié pour les applications de type serveur, où le temps de démarrage n'est pas si important
et une "phase d'échauffement" avant le code devient vraiment rapide est acceptable.
Je suppose qu'il serait possible de stocker le résultat d'une compilation JIT quelque part, de sorte qu'il pourrait être ré-utilisé la prochaine fois. Qui vous donnerait "à l'avance" compilation pour le second programme. Peut-être que les habiles gens de chez Sun et Microsoft sont de l'avis que les frais JIT est déjà assez bon et la complexité n'est pas la peine.
La ngen la page de l'outil craché le morceau (ou du moins une bonne comparaison des images natives contre JIT-compilé des images). Les exécutables compilés à l'avance de temps, en général, ont les avantages suivants:
Juste-à-temps des exécutables compilés généralement avoir la haute main dans ces cas:
La nécessité de régénérer une image qui est en avance de temps compilé à chaque fois que l'un de ses composants est un énorme désavantage pour les images natives. D'autre part, le fait que JIT-compilé les images ne peuvent pas partager le code de bibliothèque peuvent causer une grave mémoire frappé. Le système d'exploitation peut charger n'importe quelle bibliothèque native à un emplacement physique et de partager l'immuable pièces de chaque processus qui veut l'utiliser, entraînant d'importantes économies de mémoire, en particulier avec les cadres du système que pratiquement chaque programme utilise. (J'imagine que c'est un peu compensé par le fait que JIT-programmes compilés seulement de compiler ce qu'ils utilisent vraiment.)
Examen général de Microsoft sur la question est que les grandes applications généralement l'avantage d'être compilé à l'avance, tandis que les petits n'ont généralement pas.
Simple logique nous dire que la compilation énorme de MS Office taille du programme même de byte-codes vont tout simplement prendre trop de temps. Vous vous retrouverez avec un énorme temps de démarrage et qui va faire peur à personne hors de votre produit. Bien sûr, vous pouvez précompiler lors de l'installation mais cela a aussi des conséquences.
Une autre raison est que pas toutes les pièces de la demande seront utilisés. JIT compiler ces pièces que l'utilisateur se soucient, laissant potentiellement 80% de code intact, d'économiser du temps et de la mémoire.
Et enfin, la compilation JIT pouvez appliquer des optimisations que la normale compilators ne le peuvent pas. Comme l'in-lining méthodes virtuelles ou des parties de l'méthodes avec trace arbres. Ce qui, en théorie, peut les rendre plus rapides.
Une meilleure réflexion de soutien. Cela pourrait être fait en principe en avance sur le temps du programme compilé, mais presque jamais l'air de se produire dans la pratique.
Optimisations qui peut souvent être trouvé par l'observation du programme de façon dynamique. Par exemple, inline fonctions virtuelles, d'échapper à l'analyse à son tour de la pile des allocations en tas allocations, et de verrouillage de grossissement.
J'ai essayé de comprendre cela, car j'ai vu que Google est en mouvement vers le remplacement de leur Machine Virtuelle Dalvik (essentiellement une autre Machine Virtuelle Java comme HotSpot) avec Android Moment de l'Exécution (ART), qui est un AOT le compilateur, mais Java utilise généralement HotSpot, ce qui est un compilateur JIT. Apparemment, le BRAS est ~ 2x plus rapide que Dalvik... donc je me suis dit "pourquoi ne pas utiliser Java AOT ainsi?".
De toute façon, d'après ce que j'ai pu rassembler, la principale différence est que JIT utilise adaptative d'optimisation lors de l'exécution, ce qui (par exemple) permet UNIQUEMENT les parties du bytecode qui sont exécutées fréquemment pour être compilé en code natif; que AOT compile l'ensemble du code source en code natif, et le code d'un montant moindre, court plus vite que le code d'un montant supérieur.
Je pense que la plupart des applications Android sont composées d'une petite quantité de code, donc en moyenne, il fait plus de sens pour compiler l'ensemble du code source en code natif AOT et éviter la surcharge associée à partir de l'interprétation /optimisation.
Un avantage de JIT qui je ne vois pas énumérés ici est la possibilité de inline/optimiser à travers des assemblées distinctes/dll/pots (pour des raisons de simplicité, je vais juste utiliser des "assemblées" à partir de maintenant).
Si votre application références assemblées qui pourraient changer après l'installation (e. g. pré-installé les bibliothèques, un cadre, des bibliothèques, des plugins), puis une "compilation sur installer" modèle doit s'abstenir de l'in-lining méthodes dans l'assemblée des limites. Sinon, lorsque l'assemblage est mis à jour que nous aurions à trouver tous ces incorporé des morceaux de code dans le référencement assemblées sur le système et de le remplacer avec le code mis à jour.
Dans un JIT modèle, nous pouvons librement inline travers des assemblées parce que nous ne se soucient que de générer valide en code machine pour une course unique au cours de laquelle le code sous-jacent n'est pas en train de changer.
Il semble que cette idée a été mise en œuvre dans Dart langue:
https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf
Peut-être que cela a à voir avec l'approche moderne de la programmation. Vous savez, il y a plusieurs années vous écrivez votre programme sur une feuille de papier, des autres personnes pourraient le transformer en une pile de cartes perforées et d'alimenter L'ordinateur, et demain matin, vous obtenez un fichier de vidage sur incident sur un rouleau de papier pesant une demi-livre. Tout ce qui vous a forcé à beaucoup réfléchir avant d'écrire la première ligne de code.
Ces jours sont révolus depuis longtemps. Lors de l'utilisation d'un langage de script comme PHP ou JavaScript, vous pouvez tester tous les changements immédiatement. Ce n'est pas le cas avec Java, mais appservers vous donner le déploiement à chaud. C'est très pratique que les programmes Java peuvent être compilé rapide, comme bytecode compilateurs sont assez simple.
Mais, il n'y a pas une telle chose comme JIT langues uniquement. À l'avance les compilateurs ont été disponibles pour Java pour assez un certain temps, et, plus récemment, Mono l'a introduit à la CLR. En fait, MonoTouch est possible en raison de AOT compilation, non les applications natives sont interdits dans l'app store d'Apple.
La différence entre la plate-forme-navigateur-dynamique de la plate-forme et du navigateur est la façon dont votre angulaire de l'application sera compilé.
À l'aide de la plate-forme dynamique rend angulaire de l'envoi de la Juste-à-Temps compilateur pour le front-end ainsi que votre demande. Ce qui signifie que votre demande est en cours d'élaboration sur le côté client.
D'autre part, à l'aide de la plate-forme de navigateur conduit à une Avance sur le Temps de pré-compilé la version de votre application d'être envoyé au navigateur. Ce qui signifie généralement une beaucoup plus petit paquet envoyé au navigateur.
Le angular2-documentation pour l'amorçage à https://angular.io/docs/ts/latest/guide/ngmodule.html#!#bootstrap explique cela plus en détail.