Je compare deux technologies pour aboutir à une recommandation qui devrait être utilisée par une entreprise. Le code de la technologie A est interprété tandis que le code de la technologie B est compilé en code machine. Dans ma comparaison, j'affirme que la technologie B en général aurait de meilleures performances car elle ne comporte pas les frais généraux supplémentaires du processus d'interprétation. J'affirme également que, dans la mesure où un programme peut être écrit de nombreuses manières, il est encore possible qu'un programme écrit en technologie A puisse surpasser un programme écrit en technologie B.
Lorsque j'ai soumis ce rapport pour examen, le réviseur a déclaré que je n'avais pas expliqué clairement pourquoi, en général, les frais généraux du processus d'interprétation étaient suffisamment importants pour nous permettre de conclure que la performance de Tech B serait meilleure.
Ma question est donc la suivante: pouvons-nous jamais parler des performances des technologies compilées / interprétées? Si nous pouvons dire que la compilation est généralement plus rapide que l'interprétation, comment pourrais-je convaincre l'examinateur de mon argument?
Réponses:
Non.
En règle générale, les performances d'une implémentation linguistique dépendent principalement des sommes d'argent, des ressources, des ressources humaines, de la recherche, de l'ingénierie et du développement.
Et spécifiquement, la performance d'un programme particulier dépend principalement de la quantité de pensée mise dans ses algorithmes.
Il existe des interprètes très rapides et des compilateurs qui génèrent du code très lent .
Par exemple, l’une des raisons pour lesquelles Forth est toujours populaire, c’est que, dans de nombreux cas, un programme Forth interprété est plus rapide que le programme C compilé équivalent, alors que, simultanément, le programme utilisateur écrit en Forth plus l’interprète Forth écrit en C est plus petit que le programme utilisateur écrit en C.
la source
Les généralisations et les scénarios spécifiques sont littéralement opposés.
Vous semblez vous contredire. D'un côté, vous voulez faire une déclaration générale sur les langages interprétés vs compilés. Mais d'autre part, vous souhaitez appliquer cette affirmation générale à un scénario concret impliquant la technologie A et la technologie B.
Une fois que vous appliquez quelque chose à un scénario concret, celui-ci n'est plus généralisé . Ainsi, même si vous pouvez faire valoir que les langages interprétés sont généralement plus lents , vous ne faites toujours pas valoir votre point de vue. Votre critique ne se soucie pas des généralisations. Vous faites une analyse de deux technologies très spécifiques. C'est littéralement le contraire de la généralisation.
la source
En règle générale, un programme interprété est environ 2 à 10 fois plus lent que l'écriture du programme dans le langage hôte de l'interprète, les interprètes pour les langages plus dynamiques étant plus lents. Cela est dû au fait que le programme interprété doit effectuer tout le travail réel, mais qu’il a en plus la surcharge d’interprétation.
Selon la structure de l'interprète, il peut y avoir des différences très importantes. Il existe deux écoles de conception d'interprète contradictoires: l'une dit que les opcodes doivent être aussi petits que possible pour pouvoir être optimisés plus facilement, l'autre que les opcodes doivent être aussi grands que possible pour que nous travaillions davantage avec l'interprète. Lorsque la structure de votre programme correspond à la philosophie de l'interprète, les frais généraux deviennent négligeables.
Par exemple, Perl est un langage interprété orienté vers la manipulation de texte. Un programme Perl idiomatique manipulant du texte ne sera pas beaucoup plus lent qu'un programme C et peut même surpasser celui-ci dans certains cas (possible parce que Perl utilise une représentation de chaîne différente et intègre diverses optimisations liées au texte et aux E / S). Cependant, faire des calculs en Perl va être insupportablement lent. Un incrément
++x
est une instruction d'assemblage unique, mais implique plusieurs traversées de pointeurs et branches pour l'interpréteur Perl. J'ai récemment porté un script Perl lié au processeur en C ++, et une accélération de 7x à 20x, en fonction du niveau d'optimisation du compilateur.Il est important de parler d’optimisations, puisqu’un interprète poli et optimisé peut raisonnablement surpasser un compilateur naïf non optimisant. Comme la création d'un compilateur d'optimisation est difficile et demande beaucoup d'efforts, il est peu probable que votre «technologie B» ait ce niveau de maturité.
(Remarque: le site du jeu de tests de langage informatique a une structure confuse, mais une fois que vous avez atteint le tableau des temps pour un problème, vous remarquerez que la performance de différentes langues est omniprésente. Souvent, la limite de performance n’est pas clairement définie. entre les solutions compilées et interprétées. La partie la plus importante du site n’est pas les résultats de référence, mais les discussions sur la difficulté des repères significatifs.)
Lors du choix d'une technologie, les performances d'un langage d'exécution en soi sont totalement hors de propos. Il est probablement plus important que la technologie respecte certaines contraintes de base (notre budget est de x $, nous devons être en mesure de livrer avant aaaa-mm-jj, nous devons satisfaire diverses exigences non fonctionnelles) et avoir une valeur inférieure. coût total de possession (prise en compte de la productivité des développeurs, des coûts matériels, des coûts d'opportunité, des risques de bugs et des contraintes inattendues dans la technologie, des coûts de maintenance, des coûts de formation et d'embauche,…). Par exemple, dans un secteur où le délai de mise sur le marché est le facteur le plus important, la technologie offrant la meilleure productivité pour les développeurs serait la meilleure solution. Pour une grande organisation, la maintenabilité et les coûts à long terme peuvent être plus intéressants.
la source
Vous pouvez absolument dire quelque chose à propos des performances des technologies compilées / interprétées. Mais tout d’abord, vous devez définir «performance». Si vous construisez un système intégré simple en termes de calcul, les «performances» devraient probablement être orientées vers le côté utilisation de la mémoire. Alors qu’un système de calcul complexe fonctionnant sur des ensembles de données volumineux se trouverait à définir «performance» dans le nombre de calculs par unité de temps, car la surcharge de mémoire de la JVM ou du .NET serait négligeable.
Une fois que vous avez défini la "performance", vous pouvez dire: "Nous aurons 50 milliards d'objets en mémoire à tout moment et la technologie interprétée ajoute 8 octets supplémentaires à chaque objet pour la gestion interne, ce qui équivaut à une surcharge de mémoire de 400 Go. par rapport à techB qui n'ajoute pas ces données "
la source
C'est une question technique et vous avez déjà reçu de nombreuses bonnes réponses techniques, mais je voudrais souligner un aspect légèrement différent de votre situation: le fait que vous ne pouvez pas vous baser uniquement sur une décision du type "technologie A ou technologie B". pour des raisons techniques et / ou de performance.
Les aspects techniques de quelque chose comme ceci ne représentent qu'une petite partie de la décision entre A et B. Il y a des dizaines d'autres facteurs à garder à l'esprit:
Comme vous pouvez le constater, il y a une tonne de choses à prendre en compte avant de prendre une telle décision.
Je sais que cela ne répond pas spécifiquement à votre question, mais je pense que cela apporte une vue plus globale de votre situation et des détails d'une telle décision.
la source
L'évaluation partielle est un cadre conceptuel pertinent pour relier interprètes et compilateurs.
Les langages de programmation sont des spécifications (écrites dans certains rapports, tels que R5RS ou n1570 ). Ce ne sont pas des logiciels, il n’a donc aucun sens à parler de performance . Mais certains langages de programmation peuvent avoir plusieurs implémentations, notamment des interprètes et des compilateurs .
Même dans les langages traditionnellement compilés (c'est-à-dire dont les implémentations sont souvent des compilateurs) comme le C, certaines parties sont souvent interprétées. Par exemple, la chaîne de commande de format de printf (défini dans la norme C) est souvent « interprété » (par la bibliothèque standard C , qui a une
printf
fonction en utilisant des techniques arguments variables) , mais certains compilateurs (y compris GCC ) sont en mesure -in limitée spécifique cas- pour l'optimiser et le "compiler" en appels de niveau inférieur.Et certaines implémentations, même au sein d'interprètes, utilisent des techniques de compilation JIT (générez donc du code machine au moment de l' exécution ). Un bon exemple est luajit . D'autres implémentations (par exemple, Python, Ocaml, Java, Parrot, Lua) traduisent le code source en un bytecode qui est ensuite interprété.
SBCL est un "compilateur" Common Lisp qui traduit dynamiquement chaque interaction REPL (et les appels à
eval
etc ...) en code machine. Donc, vous pensez que c'est un interprète. La plupart des implémentations JavaScript dans les navigateurs (par exemple, v8 ) utilisent les techniques de compilation JIT.En d’autres termes, la différence entre interprètes et compilateurs est très floue (en réalité, il existe un continuum entre les deux) et, dans la pratique, la plupart des implémentations de langages de programmation ont souvent une facette interpréteur et compilateur (au moins codé en octets).
Une implémentation peut être rapide ou lente indépendamment de l’utilisation de la plupart des techniques de "compilateur" ou "interprète".
Certains traits de langage favorisent une approche interprétative (et ne peuvent être efficacement compilés que par une analyse complète du programme ).
Pour certains types de problèmes, la conception du logiciel avec certaines approches de métaprogrammation est intéressante et accélère considérablement. Vous pourriez imaginer que, compte tenu de certaines entrées spécifiques, votre programme génère dynamiquement du code spécialisé pour le traiter. Ceci est même possible avec C ou C ++ (en utilisant une bibliothèque JIT ou en générant du code C, en le compilant comme un plugin qui est chargé dynamiquement).
Voir aussi cette question connexe à propos de Python, et que
la source
Pour du code similaire
A = A + B
, cela peut être compilé en une ou deux instructions machine, chacune prenant un certain nombre de cycles. Aucun interprète ne peut faire la même chose dans ce nombre de cycles pour une raison simple.L’interprète exécute également un ensemble d’instructions (appelez-les octets, p-codes, langage intermédiaire, etc.). Chaque fois qu'il voit un code octet comme ADD, il doit le rechercher d'une manière ou d'une autre et créer une branche vers le code qui effectue l'addition.
La prochaine fois qu'il le verra, il devra répéter cette recherche, à moins qu'il ait un moyen de se souvenir de la recherche précédente. S'il a un moyen de se souvenir de la recherche précédente, il ne s'agit plus d'un interprète, mais d'un compilateur juste-à-temps, ou JITter.
D'autre part...
Pour un code du type
callSomeFunction( ... some args ...)
, combien de cycles sont dépensés entre la saisie de ce code et sa sortie? Tout dépend de ce qui se passe à l'intérieurcallSomeFunction
. Cela pourrait être quelques-uns, et cela pourrait être des milliards, même sicallSomeFunction
elle est elle-même compilée. Si c'est beaucoup, il ne sert à rien de débattre du coût d'interprétation de cette ligne de code - l'argent est ailleurs.Rappelez-vous que les langages interprétés ont une valeur qui leur est propre, par exemple, aucun besoin de les compiler. (La "compilation" de la syntaxe de surface en codes d'octets prend un temps trivial. Prenez R ou MATLAB, par exemple.)
En outre, la flexibilité est nécessaire pour des niveaux de programmation intelligents. Dans Minsky Society of Mind , chapitre 6.4 B- Brains, il existe des programmes A qui traitent du monde, et des programmes B qui traitent des programmes A, et il peut y avoir d'autres niveaux. Les programmes qui écrivent et gèrent d'autres programmes peuvent être plus facilement réalisés dans des systèmes d'interprétation.
En Lisp, vous pouvez écrire
(+ A B)
pour ajouter A et B, mais une fois qu'il est écrit, vous ne pouvez que le lancer ou non. Vous pouvez également écrire(eval (list '+ 'A 'B))
quelle construction du programme, puis l'exécuter. Il pourrait construire quelque chose de différent.Le sujet du programme est un autre programme . C’est plus facile à écrire dans un langage interprété (bien que, comme Jörg le fait remarquer, les versions les plus récentes de Lisp, alors qu’elles ont
eval
, compilées à la volée, elles n’ont donc pas la peine d’interpréter rapidement).la source
eval
etapply
fonctions, qui sont les interprètes.eval
n'est pas interprété. Et ni estapply
. Il existe certainement des implémentations contenant des interpréteurs, mais pas SBCL.eval
est interprétons pas ed . Il est un interprète er .En quelque sorte, cela dépend, mais en règle générale, l'environnement compilé - que ce soit par le biais de JIT ou statiquement compilé - sera plus rapide pour de nombreuses tâches de calcul intensif - en supposant que le même langage soit utilisé à des fins de simplicité.
Une partie de la raison est que les langages interprétés ont besoin d'une boucle interpréteur - boucle qui lit une instruction, sélectionne l'action appropriée à exécuter et l'exécute. Dans le meilleur des cas, comme l’interprétation du bytecode Python ou Java (comme l’avait l’ ancienne JVM), elle comportait peu d’instructions; elle causait des dégâts considérables avec le prédicteur de branche. Sans le dernier, vous pouvez vous attendre à d’énormes pénalités en raison de prédictions erronées. Même un JIT très stupide devrait accélérer cela de manière significative.
Cela dit, le langage interprété peut tricher. Par exemple, Matlab a des routines optimisées pour la multiplication de matrices et avec quelques modifications, vous pouvez obtenir du code fonctionnant sur GPU (avertissement: je travaille pour nVidia - tout avis exprimé ici est le mien et ne représente pas une vue de mon employeur). De cette façon, vous pouvez écrire du code court et puissant de niveau supérieur sans vous soucier des détails - quelqu'un s'en est occupé et a mis du temps et des ressources pour l'optimiser dans un langage de bas niveau. Il n’ya rien d’hérité et cela n’empêche pas, par exemple, Matlab d’écrire le code JIT, mais il n’ya souvent aucune raison de surcharger le fait d’appeler une routine de haut niveau est minime par rapport au temps passé dans les routines de bas niveau.
TL; DR - les programmes compilés offrent d’énormes avantages en termes de performances par rapport aux programmes interprétés (pour une comparaison de pommes à pommes, voir PyPy Speed ). Cependant, la vitesse d'exécution ne constitue qu'une partie du problème et ne contribue pas nécessairement à la vitesse globale (si le temps est principalement consacré aux bibliothèques). La mise en œuvre est également importante.
la source
Votre hypothèse est bien fondée, bien que ce soit une hypothèse.
Je ne vais pas passer en revue les raisons pour lesquelles le code compilé devrait être plus rapide que le code interprété: si vous savez comment les ordinateurs fonctionnent, ce sera évident. La différence peut être des ordres de grandeur pour certains types de problèmes. Si votre critique conteste sérieusement ce cas général, il ne sait pas de quoi il parle.
Ils peuvent toutefois se demander si la différence entre le type d’application que vous développez est importante. S'il s'agit principalement d'entrées / sorties ou d'appels de bibliothèques compilées et qu'il ne nécessite pas beaucoup de calculs, les frais généraux du processus d'interprétation risquent en effet d'être insignifiants.
Mais le but de mon message est le suivant: en tant qu’expert en informatique, vous serez souvent appelé à prendre des décisions instantanées basées sur une connaissance générale de la façon dont les choses devraient fonctionner. Faire un test spécifique peut vous apporter une réponse plus précise, mais cela coûtera beaucoup plus cher et vous ne pourrez pas y arriver en premier.
Mais de temps en temps, vous vous faites prendre. Il m'est arrivé Vous faites une bonne supposition et ensuite vous vous rendez compte que vous avez omis de prendre en compte la stupidité du monde.
Mais je ne peux pas expliquer aussi bien que mon dessin préféré de Dilbert de tous les temps. Rien ne montre mieux que le danger d'être un malin.
TL; DR: vous devriez avoir raison, mais vérifiez le monde réel au cas où.
la source
Sauf si vous utilisez quelque chose d'assez exotique, votre problème ne concernera pas les performances d'un langage interprété A et d'un langage compilé B.
Parce que si vous / votre équipe connaissez A et pas B et écrivez ainsi un code bien meilleur en A que B, vous pouvez avoir de bien meilleures performances en A que B. Si vous avez des personnes expérimentées dans une langue et que les bibliothèques / langues peuvent le faire travail dont vous avez besoin, respectez-le.
Voici un lien sur regex dans différentes langues; vous verrez que les expressions rationnelles sont mieux implémentées dans certaines langues, qu'elles soient compilées ou non: http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=regexdna
la source
Je pense que ce n’est pas une bonne idée de parler de la performance de deux technologies uniquement en se basant sur le fait qu’une est compilée et que l’autre est interprétée. Comme indiqué dans d'autres réponses, cela peut dépendre du domaine d'application (certaines langues peuvent être optimisées pour effectuer certaines opérations très rapidement et d'autres choses plus lentement), ainsi que de l'expérience de personnes sur le point d'utiliser cette technologie.
Je ne pense pas qu'il soit raisonnable de penser que vous obtiendrez une amélioration de vos performances si vous prenez quelques excellents codeurs de langage interprété et leur donnez une technologie avec laquelle ils ne sont pas familiers. Peut-être en théorie, ces derniers pourraient-ils améliorer les performances, mais en réalité, sans les compétences et l'expérience nécessaires, vous n'utiliserez pas toutes les possibilités d'optimisation.
L’un des employés bien connus de la société Silicon Valley a également déclaré préférer un langage plus simple à utiliser, car il est plus coûteux et fastidieux de payer des développeurs chevronnés pour la maintenance d’un code complexe, mais hautement optimisé, acheter plus de rig afin de faire face à la mise en œuvre moins efficace, de sorte que devrait également être considéré lors du choix de la technologie.
la source
Une fois, j'ai dû faire une déclaration rapide semblable pour justifier une grande décision.
Premièrement, ils ne veulent peut-être pas croire en un modeste ingénieur. J'ai donc trouvé des tests de référence comparables et les ai cités. Il y en a beaucoup, de gens comme Microsoft ou des universités renommées. Et ils diront des choses comme: La méthode A est entre 3 et 10 fois plus rapide que la méthode B, en fonction des variables X et Y.
Deuxièmement, vous voudrez peut-être exécuter votre propre test de performance, en utilisant peut-être un morceau représentatif du code en question ou quelque chose de similaire que vous avez déjà. Exécutez-le 1000 fois en une nuit, il y a donc une différence mesurable.
À ce stade, la différence (ou son absence) entre A et B devrait être si claire qu'il vous suffit de la présenter. Formatez donc les résultats clairement, avec des diagrammes si possible, énonçant toutes les hypothèses et définissant toutes les données utilisées.
la source
Je dirais que tout langage dynamique a un avantage sur ceux compilés de manière statique: "Optimisations d'exécution"
C'est l'une des raisons pour lesquelles Java peut être plus rapide que C ++.
Oui, charger une langue à typage dynamique aura toujours le coût de la traduction et sera désavantagé. Mais une fois qu'il est en cours d'exécution, l'interprète peut profiler et améliorer les chemins de code fréquents avec des informations d'exécution que les langages statiques n'auront jamais.
REMARQUE: Java est un langage interprété et non dynamique. Mais c’est un excellent exemple de ce que vous pouvez accélérer avec les informations d’exécution.
la source
Ce serait mon approche:
En général, les interprètes sont compilés, donc chaque technologie interprétée n’est rien d’autre qu’une technologie compilée si elle est examinée à un niveau bas. Par conséquent, les technologies compilées sont tout simplement de plus en plus nombreuses et avec plus de possibilités, vous ne pourrez jamais vous empirer si vous êtes intelligent (ce que vous êtes en général). Cela dépend de la quantité d'informations disponibles au moment de la compilation et de la quantité d'informations disponibles uniquement au moment de l'exécution et de la qualité des compilateurs et des interprètes. Toutefois, il devrait théoriquement toujours être possible d'égaler au moins les performances de tout interpréteur doté d'un compilateur approprié. juste parce que les interprètes sont fabriqués par des compilateurs. C’est possible, cela ne veut pas dire que ce soit le cas pour vos techniciens A et B.
En pratique, il suffit d'indiquer au réviseur tous les points de repère disponibles pour lesquels les systèmes compilés et interprétés sont comparés. Puis, demandez-lui de suggérer un interprète qui bat votre algorithme spécifique codé par un ensemble optimisé.
Il faut peut-être ajouter que de telles affirmations générales n’aident en rien à comparer deux techniques spécifiques, A et B. Le choix de A et B importe beaucoup plus que si elles sont interprétées ou compilées.
la source