URL: https://linuxfr.org/news/un-projet-de-vm-python-chez-dropbox-et-etat-des-lieux-des-autres-vm Title: Un projet de VM Python chez Dropbox et état des lieux des autres VM Authors: Philippe F palm123, BAud, Nÿco, sleibo, Nonolapéro, Maxime et Jiehong Date: 2014年04月07日T09:10:14+02:00 License: CC By-SA Tags: python, pypy, numba, cpython, ironpython et pyston Score: 50 Dropbox lance PySton, une nouvelle implémentation de Python, basée sur [[LLVM]], avec comme objectif de tirer partie des capacités [JIT](http://fr.wikipedia.org/wiki/Compilation_%C3%A0_la_vol%C3%A9e) (Just-In-Time compiling, compilation à la volée) de l'architecture LLVM. Le but étant à terme d'utiliser Python là où du C++ était encore utilisé pour ses performances. La suite de la dépêche fait un état des lieux des différentes VM Python et des projets d'améliorations de leur performances. ---- [L'article sur le blog de Dropbox](https://tech.dropbox.com/2014/04/introducing-pyston-an-upcoming-jit-based-python-implementation/) [Le projet github](https://github.com/dropbox/pyston) [L'annonce sur la liste Python-dev](https://mail.python.org/pipermail/python-dev/2014-April/133772.html) ---- Avant de vous parler du projet initié par Dropbox, faisons un petit tour des VM disponibles pour Python. # CPython # L'implémentation de référence du langage Python, en C. La syntaxe Python est convertie dans un _bytecode_ Python, qui est exécuté par la VM CPython. On critique régulièrement cette VM, à tort. Elle fonctionne très bien, elle est très portable et a subi de nombreuses optimisations au fil du temps qui en font une VM robuste, rapide et fiable. On lui reproche régulièrement son GIL, le Global Interpreter Lock, ce gros verrou global qui protège les accès _multi-threads_. Dans les faits, le problème du GIL ne se pose que pour les programme multi-threads, CPU-bound, exécutés sur des multi-coeurs, qui se prêtent mal à d'autres techniques de parallélisme (tel que les services offerts par le [module multiprocessing](https://docs.python.org/3/library/multiprocessing.html)). Autant dire qu'on est dans des développements très spécifiques qui n'affectent pas la majorité des programmes écrits en Python. Le GIL introduit par ailleurs des simplifications de code massives qui expliquent sa présence et sa longévité. # IronPython # [IronPython](http://ironpython.net/) une implémentation du langage Python, basée sur le [CLR] (http://fr.wikipedia.org/wiki/Common_Language_Runtime) du framework .NET de Microsoft. Elle profite de tout l'écosystème autour de .NET et notamment des capacités JIT du CLR. Sur les derniers benchmarks dont je me rappelle, IronPython était soit au niveau de CPython, soit plus rapide (sans pour autant exploser les compteurs, on était dans le 1.5x ou 3x sur des benchmarks très ciblés). Si le langage est bien supporté, on peut regarder au delà de la communauté Python et se mettre à rêver grâce à IronPython de convertir des programmeurs Visual Basic. Ça, c'est pour la pub. Quand on regarde de près, on découvre qu'en fait, pour les langages dynamiques comme Python, Ruby et Javascript que Microsoft prend en charge, le CLR brut est mal adapté. Microsoft a donc créé un DLR, un _Dynamic Langage Runtime_, qui s'interface au dessus du CLR et fournit des services particuliers pour gérer le _dynamisme_ des langages précités. Jusque là, très bien... Pour faire fonctionner un programme IronPython, il faut donc en plus des dernières versions de .NET installer le DLR dernière version. Moyennant tout ça, un programme Python pourra utiliser facilement n'importe quel composant .NET (écrit en C#, J#, Visual Basic...) mais l'inverse n'est pas vrai : un programme Python ne peut pas produire simplement des objets compatibles CLR et reste cantonné au monde du DLR. Pour accéder à ces objets/bibliothèques depuis un programme CLR, il faut passer par une gymnastique un peu complexe. Du coup, les langages DLR ne sont pas du tout au même niveau que les langages CLR et il y a peu de chance de voir Python remplacer un jour le Visual Basic. Récemment, Microsoft a ~~décidé de se débarrasser de ce truc~~ donné IronPython à la communauté. Le développeur principal du projet chez Microsoft, après avoir vu son équipe se réduire au fil des mois, est finalement parti chez Google. Cf [cet article de ZDNET](http://www.zdnet.com/blog/microsoft/microsoft-offloads-ironruby-and-ironpython-languages-to-external-developers/7790) qui résume bien ce qui se passe. Autant dire que IronPython n'apportera pas la révolution que certains attendaient. Ca reste un projet très respectable, avec des versions compatibles 2.7 complètement fonctionnelles et une intégration dans Visual Studio. # Jython # [Jython](http://www.jython.org/) est une implémentation de Python pour la JVM de Java, qui permet d'écrire du code Java en Python et d'utiliser tous les bibliothèques Java en Python. Il supporte Python 2.5 et 2.7 . On en entend peu parler dans le monde de l'Open Source mais le projet continue son bonhomme de chemin depuis plus de 10 ans maintenant (la première version est sortie autour des années 2000). Cette longévité est un signe que le projet est utilisé, très probablement dans le milieu de l'industrie. Les performances sont à peu près au niveau de CPython (dixit la FAQ), le temps de démarrage d'une appli est assez long (à cause de la JVM, c'est donc peu pratique pour des scripts) ; sur des programmes qui s'exécutent longtemps (comme c'est souvent le cas pour des applis java côté serveur), le compilateur JIT JVM se met en route et fournit des gains intéressants. À noter l'addition récente du module [JyNI](http://jyni.org/) qui permet d'utiliser les modules d'extension Python de façon transparente en Java. L'intérêt principal de ce projet, ce ne sont pas les performances mais l'intégration transparente dans l'écosystème Java. Si la JVM gagne encore en performance, le projet en bénéficiera, mais cela fait longtemps qu'on n'entend plus de nouvelles révolutionnaires sur le sujet... # PyPy # On ne présente plus [PyPy](http://www.pypy.org), l'interpréteur JIT Python qui déménage. Après plus de 12 années et 5 réécritures, le projet envoie du bois : ça exécute du Python plus vite que CPython et [pas qu'un peu si on en croit les benchmarks](http://speed.pypy.org/). Note de l'auteur: sur un programme ordinaire, tout le monde ne voit pas de tels gains, voire voient des dégradations catastrophiques donc à prendre avec du recul. Le projet génère du code x86, x86-64 et récemment Arm (suite à un effort du projet Rapsberry Pi). Il est compatible Python 2.7, avec un effort en cours pour avoir la compatibilité Python 3. Le projet a maintenant atteint un bon niveau de stabilité et de performance, suffisant pour l'utiliser en production. Il est utilisable notamment avec Django, SQLAlchemy ou Twisted. Maintenant que les gains sont là, les efforts portent sur l'écosystème ou sur d'autres innovations. Côté écosystème, le gros problème de PyPy est que tous les modules d'extensions compilés pour CPython ne fonctionnent pas sous PyPy. Et il y en a beaucoup : des GUI (PyQt, PyGtk...), des bibliothèques de jeu (PyGame), etc. PyPy travaille sur le sujet mais sans espoir pour l'instant de résoudre complètement le problème : * dans certains cas, une recompilation dudit module pour PyPy avec cpyext permettra de le faire fonctionner. * sinon, il faut envisager des méthodes alternatives pour faire le lien C/C++ et PyPy. Il y a des projets vraiment sympa comme Reflex, cffi et autres (cf [Writing extensions modules for PyPY](http://pypy.readthedocs.org/en/latest/extending.html)) mais au final, on est dans une approche qui demande une réécriture partielle dudit module. Un certain nombre de projets sont compatibles PyPy . En plus de ceux que j'ai cité, on peut consulter la liste sur [la page de compatibilité PyPy](https://bitbucket.org/pypy/compatibility/wiki/Home). Dans le cas particulier de NumPy, compte-tenu de son importance pour la communauté PyPy (ou en tout cas d'un de ses auteurs qui travaille dans la recherche scientifique), une réécriture spécifique pour PyPy a été démarrée sous le nom de [NumPyPy](http://pypy.org/numpydonate.html). Celle-ci ne fait pas l'unanimité, les développeurs autour de NumPy arguant d'une part qu'un clone est moins pratique que l'original, d'autre part qu'il y a d'autres modules d'extensions indispensables pour fonctionner dans l'écosystème (matplotlib, SciPy...). Côté innovations, PyPy expérimente maintenant les **Software Transactional Memory**, c'est-à-dire gérer les accès mémoire d'un programme _multi-threadé_ avec des transactions, comme dans une base de données. Une transaction pourrait être commencée, mise en œuvre ou annulée. L'approche est originale, et a pour but de se débarrasser du GIL. Pour l'instant, c'est très lent, il est prévu un ralentissement de 2 à 5 par rapport à du CPython de base, mais cela offre en théorie la possibilité de tenir une forte montée en charge. Pour l'instant, on est vraiment sur un sujet de recherche donc à voir d'ici quelques années. Il y a aussi un projet PyPy Sandbox qui permet d'isoler proprement un programme Python de son environnement. Les autres projets de ce type ont toujours échoué, Python offrant de multiples mécanismes de contournement de Sandbox. La force de PyPy est de pouvoir faire la Sandbox à un niveau très bas donc ça peut marcher. Pour l'instant, il y a peu de retour sur ce projet. PyPy est un beau projet, il a su tenir son cap à travers les années - faisait fi des sceptiques - et nous délivrer ses promesses. Aujourd'hui, c'est à la fois une implémentation de Python rapide et un framework de génération d'interpréteurs Python. Il a même été utilisé très sporadiquement pour d'autres langages. Il a plus été pensé pour un usage scientifique au départ (biais de son auteur) mais les modules qui fonctionnent officiellement bien en PyPy (django, SQLAlchemy, Twisted) font penser que c'est sur les serveurs d'application qu'il va finalement faire une différence... Le problème des modules d'extension est malheureusement rédhibitoire dans beaucoup de situations. Il est rare qu'un programme Python n'aie aucune dépendance vers une bibliothèque compilée et l'approche qui consiste à réécrire ledit module spécifiquement pour PyPy n'est pas toujours possible. # Numba # [Numba](http://numba.pydata.org/) est un compilateur JIT/LLVM pour Python, qui transforme des morceaux de Python annotés vers la chaîne de compilation LLVM. Le code doit être annoté explicitement avec des marqueurs du type *@jit* pour demander une compilation générale vers LLVM, soit en laissant LLVM générer le code à la volée en fonction des types passés à la fonction, soit en spécifiant dans les annotations les types à utiliser. Le site ne fournit pas de benchmarks explicites mais explique que les performances sont au niveau du C, le code Python étant effectivement traduit en assembleur. L'approche permet par exemple d'appliquer facilement des calculs sur des tableaux NumPy. C'est un projet spécialisé dans le calcul hautes performances. On ne parle pas ici d'optimisation générale d'un programme en Python, mais d'optimisation explicite d'une ou plusieurs fonctions avec compilation au démarrage du programme (et non à la volée). # Unladen Swallow # Ce [projet](https://code.google.com/p/unladen-swallow/) lancé en 2009 par trois ingénieurs de Google avait l'ambition d'accélérer la VM Python par un facteur 5, en s'appuyant sur l'architecture de compilation JIT du projet LLVM. Une des contraintes était de garder une compatibilité totale avec CPython et notamment avec les modules d'extension Python écrit en C. Unladen Swallow est parti de la VM de CPython et a modifié la boucle d'exécution principale pour émettre du bytecode LLVM. Un programme Python était d'abord traduit en bytecode Python classique, puis transformé à la volée et selon les besoins dans la chaîne LLVM pour aboutir à du code assembleur. On avait donc à toutes les étapes du projet un compatibilité 100% avec les programmes Python existants, validée par une grosse suite de test multi-projets. Le projet a bien débuté, avec des gains intéressants au départ. Une PEP a aussi été acceptée par Guido van Rossum pour intégrer Unladen Swallow dans CPython (alors même que Unladen Swallow n'avait pas encore livré toutes ses promesses -- cette décision a été un peu critiquée). Au bout d'un an, le projet a été arrêté et la PEP annulée. En cause, d'une part un nombre important de bugs dans la compilation à la volée dans la suite LLVM qui ont fortement ralenti la progression attendue. D'autre part, le manque d'adoption interne chez Google, les développeurs étant finalement assez contents de leur CPython de base. Un post d'un des développeurs résume la situation finale : [Unladen Swallow Retrospective](http://qinsb.blogspot.fr/2011/03/unladen-swallow-retrospective.html). Le projet a quand même produit 4 versions, chacune plus rapide, ainsi qu'une suite de benchmarks de référence pour Python, assemblant tout en ensemble de suite de tests et benchmarks existants. # Le dernier né : Pyston # Dropbox (chez qui travaille maintenant Guido Van Rossum) nous annonce donc un nouveau de projet de VM : Pyston. Quelques liens : l'annonce et le code * https://tech.dropbox.com/2014/04/introducing-pyston-an-upcoming-jit-based-python-implementation/ * https://github.com/dropbox/pyston Ce sera une implémentation par dessus LLVM et son JIT d'une VM Python complète. Le projet vise au départ une compatibilité Python 2.7, avec un backend x86 uniquement. Les développeurs sont partis de l'observation que dans le monde Javascript, les plus gros gains de performances ont été faits avec un _compilateur JIT par méthode_ au lieu d'un _tracing JIT_ qui va se concentrer sur des boucles. PyPy ayant déjà montré les gains qu'on peut avoir avec un _tracing JIT_, ils ont eu envie d'explorer l'autre versant de la compilation à la volée. Pyston est une implémentation avec LLVM de l'interpréteur Python. Le langage Python est compilé en byte-code LLVM et la chaîne de compilation LLVM prend le relai pour ce qui concerne les optimisations et la compilation JIT. C'est une grosse différence par rapport à Unladen Swallow qui se penchait sur l'optimisation de la VM CPython : on est là sur une réécriture complète. L'inconvénient est qu'il faut implémenter toute la logique du langage, un travail considérable : impossible de réutiliser l'infrastructure existante de la VM CPython. Les développeurs perdent aussi tout le savoir-faire qu'il y a déjà dans Python pour l'optimisation de la boucle d'évaluation. L'avantage plus ou moins théorique est que l'optimisation peut être plus transversale puisqu'on évite un étage de traduction. Le projet a aussi changé le _garbage collector_, passant du comptage de référence de CPython à un *ramasse-miettes Conservateur*. Sur les modules d'extension, le changement de _Garbage Collector_ rendra ceux-ci nécessairement incompatibles et il y a un vague plan pour corriger cela. Les développeurs ont l'air conscients de l'ampleur du travail à effectuer, notamment pour se rapprocher des performances de PyPy. Pour l'instant, le prototype prend en charge un tout petit sous-ensemble du langage Python. Celui-ci aurait montré d'après les développeurs un bon potentiel en terme de gain de performance. Depuis le projet Unladen Swallow, LLVM a continué à s'améliorer et la partie qui avait posé tant de problème à Unladen Swallow a été réécrite. Les développeurs Dropbox espèrent donc ne pas subir les problèmes qu'a connu Unladen Swallow avec LLVM, ce qui tend à être confirmé par les résultats du projet Numba. Il faut être bien conscient que même si LLVM fournit une chaîne de compilation JIT de bonne qualité, il y a beaucoup de travail à fournir en amont : l'interprétation du langage Python, le traçage des types, l'activation sélective du JIT, la gestion de la durée de vie des morceaux compilés. Il y aura beaucoup d'ajustements à trouver sur la consommation mémoire globale et sur les conditions d'activations du JIT. Par la suite, ils envisageront une compatibilité Python 3, d'autres backends de génération de code, un meilleur _Garbage Collector_, l'intégration plus ou moins transparente des modules externes et même de se pencher sur le GIL. # Commentaire de l'auteur # Je précise que je n'y connais rien en compilation, LLVM ou JIT, j'ai juste plaisir à suivre de près ces projets très pointus. La rédaction de la dépêche a fait ressortir que les efforts d'accélérations de Python, même s'ils sont réussis, butent presque tous sur la prise en charge transparente des modules d'extension. C'est vraiment un gros point noir, difficile à résoudre, et pourtant majeur. Les programmes Python qui tournent sans dépendances sont à mon avis minoritaires. Même s'il y a un effort un jour pour recompiler facilement vers PyPy ou autres, on tombera toujours sur le module un peu spécifique à un domaine qui ne fonctionnera pas. Pyston, en ayant notamment changé le Garbage Collector, se range dans la même catégorie. Seul le projet Unladen Swallow avait une approche globale sur le sujet avec une compatibilité totale. Ça aurait permis à n'importe quel programme Python de bénéficier des optimisations JIT, et ce à un coût de migration négligeable. L'autre point qui me frappe au sujet de Pyston, c'est une certaine innocence dans l'approche (on pourrait presque dire naïveté). À leur lancement, les projets PyPy et Unladen Swallow avait une idée très précise et documentée de là où ils voulaient aller, articles de recherche à l'appui. On sentait qu'il y avait eu une analyse en profondeur du sujet. Pour Pyston, ça ressemble plus à « tiens, pour Chrome, le per-method-JIT a bien marché, on a qu'à faire pareil avec Python et LLVM » . Il y a de très beaux projets qui sont issus d'une telle approche, mais aussi énormément qui se sont plantés parce qu'ils ne savaient pas où ils allaient. Le choix de réimplémenter toute la VM Python est quand même très costaud, et implique qu'on ne verra pas de résultats utilisables avant au moins un an, voire plusieurs. Souhaitons en tout cas longue vie à ce projet et bon courage à leur développeurs ! # Post-scriptum # Il y a plein d'autres efforts pour accélérer Python d'un façon d'un autre, autrement qu'en tapant dans la VM. Allez voir sur le site de Haypo [la page qui y est consacrée](http://www.haypocalc.com/wiki/VM_Python) si vous voulez en savoir plus, ou encore [ses notes sur la vitesse de Python](http://haypo-notes.readthedocs.org/faster_cpython.html).

AltStyle によって変換されたページ (->オリジナル) /