Pourquoi les implémentations de JITted Python sont-elles encore lentes?

Je comprends pourquoi les frais d’interprétation sont coûteux, mais pourquoi les implémentations de JITted Python (Psyco et PyPy) sont-elles encore beaucoup plus lentes que d’autres langages JITted comme C # et Java?

Edit: Je comprends aussi que tout est un object, que le typage dynamic coûte cher, etc. Cependant, pour les fonctions où des types peuvent être déduits, je ne sais pas pourquoi cela compte.

La réponse la plus simple possible est que PyPy n’est tout simplement pas aussi rapide que le hotspot et que Psyco ne le sera jamais.

Écrire une EMI raisonnable est un processus long et fastidieux et il a par exemple fallu de nombreuses années à hotspot pour arriver à destination (avec beaucoup de financement également). Plus la langue est complexe et dynamic, plus elle prend du temps. Du bon côté des choses, nous avons de bons exemples de la façon dont les JIT pour les langages dynamics peuvent être très rapides, prenons LuaJIT pour un, qui peut battre C ou JVM sur de nombreux exemples.

Il y a toutefois une bonne nouvelle: selon le centre de vitesse, PyPy a progressé de 27% en moyenne en moyenne au cours des 100 dernières révisions, ce qui finira par se produire.

Les gens ont déjà souligné les détails techniques, alors j’appendai un autre facteur: l’argent.

Au cours des dernières années, les machines virtuelles Javascript (V8 de Google, Tracemonkey & Jaegermonkey de Mozilla, Nitro d’Apple) ont permis une augmentation considérable de la vitesse pour un autre langage dynamic. Cela tient en grande partie au désir de Google de rendre les applications Web plus puissantes. Python n’a tout simplement pas la réputation d’une grande entreprise de gagner 50x plus rapidement.

Oh, et l’intégration avec les extensions C comme numpy signifie que la vitesse est rarement critique pour le code Python, de toute façon.

Python est un langage dynamic .

Cela signifie qu’une grande partie du travail effectué par d’autres langages statiques (tels que C # et Java) lors de la compilation est effectuée lors de l’exécution, ce qui réduit les performances.

MODIFIER:
De plus, le compilateur JIT pour un langage dynamic comme python peut effectuer beaucoup moins d’optimisations sur le code car il ne peut pas faire beaucoup d’hypothèses en raison de la dynamicité du code.

par exemple
Le typage dynamic empêche les suppositions sur le type de champs / variables / parameters …, donc toute optimisation impliquant cela est presque impossible.

EDIT2:
juste une clarification:
quand je parle de temps de compilation, je veux aussi dire du temps de compilation JIT, car JIT est en fait un compilateur.
En appliquant cela à ma première phrase, Python peut effectuer beaucoup moins de travail au moment de JIT que C # ou Java …

Une très bonne question. Je ne peux pas vous donner une réponse complète, mais je pense que l’une des raisons est le concept “tout est object et un object peut être n’importe quoi”. En Java, si vous essayez “1.getClass ()”, cela ne fonctionnera que si vous le boxez au préalable, explicitement ou implicitement. En Python, cela fonctionne hors de la boîte. Mais les objects sont nettement plus lourds que les types primitifs, ce que Python ne semble pas avoir.

La partie “un object peut être n’importe quoi” est encore plus importante. Si vous écrivez “someobject.somefield” en Java, il sait au moment de la compilation ce qu’est exactement “somefield” et génère un code qui y accède directement. Eh bien, il existe probablement quelques astuces pour améliorer la compatibilité binary, mais cela n’a rien à voir avec Python, qui effectue une sorte de consultation du dictionnaire au moment de l’exécution pour déterminer ce qu’est exactement un “champ” à ce moment particulier, car les champs peuvent être ajouté et supprimé dynamicment.

En bref, Python est plus puissant, mais ce pouvoir a un coût.

Vous ne pouvez pas vraiment comparer les langages dynamics aux langages statiques d’entreprise. Sun a dépensé beaucoup d’argent pour optimiser la langue, VM et JIT. Microsoft a également fait un travail juste avec leur VM.

Il est plus intéressant de comparer les langages dynamics jit’ed. Est-ce quelque chose à propos de JavaScript qui permet à Google de créer leur V8 plus rapidement que PyPy et Ruby 1.9 ou qu’il s’agit simplement d’une sum d’argent que l’on investit?

Je comprends pourquoi les frais d’interprétation sont chers …

Comparez ces implémentations Python à du Java en mode interprété non JIT et réfléchissez à nouveau à votre question.

Toute la question n’est plus aussi claire en 2014. Le moteur V8 JS de Google fait des choses assez lourdes pour optimiser l’enfer de js.

PyPy pourrait être beaucoup plus rapide si seulement assez d’argent était disponible. La vitesse d’exécution de Python importe peu, donc personne n’investit lourdement dans PyPy.

Ce n’est vraiment plus un problème technique. Regardez l’instruction InvokeDynamic de Java. Bien sûr, ces invocations coûtent plus cher la première fois qu’elles sont appelées, mais la machine virtuelle Java peut effectuer des tâches magiques une fois que ces invocations ont démarré. C’est-à-dire que la machine virtuelle Java peut faire des suppositions et en apprendre davantage sur le code tout en l’exécutant. Si une méthode retourne toujours un int, il est possible que cette méthode retourne toujours un int. En réalité, la JVM fait beaucoup plus.

En 2014, ce n’est vraiment pas dynamic ni statique en termes de performance. Certes, C ++ sera toujours l’outil le plus rapide du marché, mais les langages dynamics jitted ne sont pas plus “lents” qu’ils l’étaient il ya quelques années.

Attendez encore quelques années, je parie que l’parsing statique est beaucoup plus forte en 2016 ou 2017. Il existe actuellement quelques projets de recherche très intéressants.

En théorie: vous pouvez en principe déduire chaque type à l’aide de l’parsing de type statique, vous devez comprendre ce que le code fait avant de le faire. Ce n’est pas impossible

Lorsque l’parsing statique devient plus puissante, vous n’avez plus vraiment besoin d’un système de type statique. Tous les systèmes de types statiques, même ceux de haskell, limitent le nombre de programmes corrects. Donc, en substance: si vous avez un parsingur capable de prouver l’exactitude d’un programme en l’analysant, il est beaucoup plus puissant qu’un système de type statique qui ne peut agir que dans les limites. Et concernant la réutilisation de code: Rien ne peut battre la frappe dynamic.

Certains diront que le typage dynamic est mauvais pour les applications volumineuses, mais si l’parsing statique devient plus puissante, vous obtiendrez la même exactitude, voire peut-être, une exactitude bien plus prouvée qu’un système de type statique pourrait jamais offrir. Bien sûr, les langages à typage statique pourraient également être analysés statiquement, mais le système de type statique serait inutile.

Donc, en substance: voici beaucoup de si, je sais. Mais il y a 10 ans, les gens auraient ri si vous leur aviez dit que js devenait si rapide que vous pouviez facilement y écrire de lourdes applications 3D opengl.

Ne sous-estimez jamais l’avenir.