François Pinard's site |
||
Pyrex
1 What is Pyrex?Pyrex is a kind of Python compiler, written by Greg Ewing, which produces C code. That C generated code allows for both-way interfacing between real Python code and any C module. However, Pyrex does not exactly compile pure Python. First, there are a few missing features from the Python; yet in my experience, this does not create a problem in practice). Second, one may decide to declare, using C-like specifiers, a fixed type for some variables, arguments or functions. Such declarations, when they exist, let Pyrex produce speed optimisations. For interfacing between Python and C, Python documents an API for C. Such interfaces are somehow cumbersome to write perfectly, as tiny errors (particularly in the area of reference count administration) could produce far-reached and asynchronous effects, the kind of bugs where one might loose some hair. Pyrex invites you to think in C (yet also in Python) while using Python syntax, a rather elegant compromise in my opinion. For me, besides allowing nearly-Python syntax while thinking in C, Pyrex automatically and safely takes care of this error-prone reference administration. These two features combine into an immense advantage. While it is true that Pyrex could be used to speed up Python, I see it more as an elegant and simple way to build interfaces from Python to C libraries or C modules, and vice-versa. In my applications at least, the speed-up of Python-style code is welcome of course, but incidental. I got success with Pyrex as a way to recover about all of the C speed, once analysed the bottlenecks, without actually writing any new C. So, the argument that Python is slow does not hold so much anymore. All in all, Pyrex is amazingly well thought, this is a wonderful tool. 2 Miscellaneous notes
3 Cheat sheetThe following set of facts is a reminder of the real documentation, and in no way a replacement for it. 3.1 Installation details
3.2 Python aspects
3.3 C aspects
3.4 Pyrex pre-processor
3.5 Pyrex simple statements
3.6 Pyrex compound statements
3.7 Useful declarations
4 Usage notesI would not hesitate to use a global variable to get the effect of a class variable. When one writes Pyrex, one has to think assembler (or C!) a bit. Pyrex is the good tool for establishing a compromise between Python elegance and C speed, so I'm also ready to think in compromise mode when using it. If we want the feel that we deeply understand the relation between the Pyrex special constructs and the speed we can get from them, we have to get used to the exact meaning of these constructs, and look at the generated C code once in a while. That's easy and that's worth. Moreover, I surely learned many good things about Python internals by using Pyrex as a teacher. ☺ 5 Embedding Python in COne nice
possibility of Pyrex, which is not documented enough in
my opinion, is its capabilities for embedding Python
within what would otherwise be a pure C application.
Instead of long explanations, let me take an excerpt of a
real example. The following is statique.pyx, it
links and uses ammodule.pyx, compiled separately.
That could have been importable Python code just as well.
Of course, main_application may be anything:: I sometimes abuse
this feature to statically link, in view of
gdb debugging. In the case above, it was just some
code to trigger a bug I wanted to explore. The initammmodule() call is needed here
because of static linking, but is seemingly not required
when dynamically loading through import. Here is an example of the
actual gcc and link calls:: In fact, the actual setup I used is a bit more simpler for my users, as a site-wide common Makefile hides the pyrexc calls and linking mechanics within builtin rules. We also once used a home-grown pre-processor for Python code which takes care of part of the main expansion, above. 6 Python-free applications?The Recodec project uses Python for prototyping what could become the next major version of my older Recode project, itself written in C, and which is traditionally installed as a single Python-free, big executable. The migration plans from Recodec to Recode are still fuzzy. One avenue to ponder is Pyrex, if I could find a way to cut the wires between Pyrex and the Python runtime library. While Pyrex generates C code, it includes many things for Python module administration, reference counting, and library calls. Extracting the pure C code out of this might be difficult. I sometimes dream that it would be possible to provide a module containing many stub routines or minimalistic routines, for representing the Python library, but I do not know yet how possible this could be. For the next Recode, Pyrex would then allow me to stick to the pleasure of Python-like syntax, of course. Here, I could build and debug prototypes in Python, with the agenda of later transforming them into C, somehow, without rewriting so much of them, for environments like Recode where the whole of Python, for various reasons, is not welcome. The main concern is speed. Not only CPU speed, but also avoiding, through loading a single executable file, sparing the many hundreds of disk accesses which occur each time the Python interpreter is started. In this project, I want to explore how fully one could get rid of the Python interpreter while using Pyrex, maybe through a set of added stub routines, but this project is low priority and I'm not getting there yet. One of these days hopefully. The nice thing with Pyrex is that you can use the Python interpreter, or not use it, more or less depending on your way to declare things and your way to code. So, in a way, you have full control over the compromise between speed and facility. The temptation is always strong to use Python facilities, but I guess that with enough discipline, you can displace and put the equilibrium wherever you want. If you tolerate having the Python interpreter around, I presume that you can take good advantage and be happy of its presence for the many parts of your programs where speed is not that critical. If you do not want the Python interpreter around in the long run, and if this is possible to fully get rid of it (I do not know yet), then there is no doubt to me that one needs a fairly strict discipline while using Pyrex. 7 Reclasser
7.1 détails
7.2 docs
|
||