URL: https://linuxfr.org/users/serge_ss_paille/journaux/pythran-python-c Title: pythran: python -> c++ Authors: serge_sans_paille Date: 2012年07月08日T14:58:50+02:00 License: CC By-SA Tags: pythran, python, c et compilateur Score: 30 La lecture quotidienne des journaux m'avertit qu'il y a de nombreux pythonistes dans le coin, alors... Dans ma pratique régulière du Python (et n'oubliez pas : manger 5 langages par jour pour être bien en forme !), je prends un grand plaisir à coder des algos à base de liste / ensembles / dictionnaires le tout dans une petite sauce fonctionnelle. C'est loin d'être la seule façon de programmer en Python mais c'est comme ça que je fais. Bien sûr, tout ceci ne s’exécute pas ultra rapidement, mais c'est généralement le cadet de mes soucis. Sauf quand ça le devient. Dans ce cas que peut-on faire ? # Biblio rapide # * utiliser l'[API C](http://docs.python.org/c-api) de Python directement. C'est pas ultra sorcier, un peu de glue et on a le plaisir de faire du C derrière. * [boost::python](http://www.boost.org/libs/python/doc/) est assez sympa aussi, moins de glue, et on a le plaisir de faire du C++. * [ctypes](http://docs.python.org/library/ctypes.html) est tout ce qu'il y a de plus standard, et permet d'appeler des bibliothèques externes depuis son code python. Un bon choix si on a déjà le code C/C++ sous la main. Il parait que [cffi](https://bitbucket.org/cffi/cffi) est du même acabit mais je n'ai pas testé. * [shedskin](http://shed-skin.blogspot.fr/) en voilà un outil qu'il est bien, puisqu'il prend un module python implicitement typé statiquement, et nous transforme ça en module natif. Avec des speedup pas dégueux du tout * [pymothoa](http://code.google.com/p/pymothoa/) plus jeune et qui nous crache du bytecode llvm. Par contre, le typage est explicite et ça ... berk et le dialecte supporté est un peu faiblard * [copperhead](http://copperhead.github.com/) qui a plutôt un statut de recherche mais qui propose de porter nos bébés serpents sur GPU, rien que ça. Comme tout à un prix le sous langage utilisé est très orienté (curieux !) _data paralellism_. # Toi, toi, toi, tu ressembles à celle # Alors voilà, j'ai joué avec les uns et les autres, goûté à tout (très bon pour le teint) et pour mettre à profit les trois années de thèse passée, je me suis fondu d'un nouveau membre pour cette belle famille, [pythran](https://github.com/serge-sans-paille/pythran). Le reste du journal parle de ce **magnifique** projet. ## kezaco ## Un convertisseur automatique d'un sous ensemble de python (sans classe ni introspection) vers du c++ ## Ça va vite ? ## (bah oui faut bien motiver les troupes) Dans les bons jours, on va 30 fois plus vite que du CPython, et 1.5 fous plus vite que du shedskin. Pas regardé pour les autres encore. Dans les mauvais deux-trois fois plus lent à cause du coût de conversion listes python -> tableaux natifs (on laisse de côté les tableaux numpy pour le moment) ## Comment ça marche ## Bien (ahah). En gros l'idée c'est d'exploiter à fond les fonctionnalités du dernier standard C++ pour déporter la complexité du compilo sur le compilo C++, qui a une propriété terriblement géniale : quelqu'un d'autre l'a déjà écrit. Par exemple pour typer le p'tit bout de code suivant ```python a=[1,2,3.] for i in xrange(a): print i ``` On va essayer de générer du code de ce genre là ```c++ std::vector< decltype( 1 + 2 + 3.)> a = { 1, 2, 3. }; for(auto i: xrange(a)) print(i); ``` Alors la première partie, c'est d'écrire un runtime C++ qui va nous fournir tous les _builtins_ python : [ceux là](http://docs.python.org/library/functions.html). À grands renforts de `template` et de foncteurs, on s'en sort pas trop mal. Merci les _variadic template_ pour implémenter des jolis `map`, `reduce` et autre `zip`. Ensuite faut gérer le [polymorphisme](http://en.wikipedia.org/wiki/Type_polymorphism). Pour les fonctions, la p'tite astuce c'est de toutes les déclarer comme template, par exemple ```python def mul(self, other): return self*other ``` deviendra ```c++ template auto mul(T0 const& self, T1 const& other) -> decltype(self*other) { return self * other; } ``` En poussant l'idée à l'extrême, on peut transformer un module complet en un gros pâté de fonctions _template_ dont chacune des variables locale a un type calculé à coup de `decltpe` à partir de ceux des paramètres formels. La classe ! ## Ça a l'air cool, je veux essayer ## Fastoche, après avoir suivi les instructions cachées sur le [site web](https://github.com/serge-sans-paille/pythran), tu pourras t'essayer à un joli ```shell pythran -E mon_module.py ``` Qui ne marchera que si tu as fourni au bousin une ligne du genre ```python #pythran export foo(int) #pythran export foo(complex) ``` pour lui dire que parmi toutes tes zolies fonctions, tu veux en exporter deux, avec les signatures idoines. Je passe sur pleins d'autres aspects rigolos, et je vous invite à tester la bête, ce qui devrait vite l'épuiser et montrer ses limites, une belle occasion de l'améliorer !

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