Cython vs. binding generators

This year's PyCon-US included a talk with the rather lurid title "Cython vs. SWIG, Fight!". I'm sure many of the attendees expected something different than they actually got, which was mostly a featurewise comparison at the "this is how some basic examples might look" level. In fact, I think the difference between Cython and SWIG, or actually Cython and any of those binding generators or wrapping tools, can be summarised in two words. They are binding generators, whereas Cython is a programming language, with all its expressiveness.

Cython's main selling point is that it completely blurs the border between Python and C. A binding generator, or a foreign language interface tool like ctypes or cffi, will only ever give you the choice of two extremes:

  1. write your code in Python and let it talk to wrapped C, or
  2. write your code in C and wrap it.

Either easy or hard, nothing in between, and it's not always your choice. They give you no help at all with the parts where it needs to be hard for some reason, and some do not even reduce that unfriendly feeling of working with truly foreign code. Even worse, these tools usually have a very specific idea about how the wrapping should look like, so if you come to a point where you're not happy with the way they work, you'll have to start working against the tool.

Cython is different. With Cython, you can

  1. write your code in Python and let it talk to wrapped C
  2. compile your Python code
  3. add static type declarations to your Python code to specialise and speed up the result of the compilation
  4. change your Python code file extension to ".pyx" to start using elements of the Cython language that let your code talk to C directly (note that this makes it Cython code)
  5. write your code in the Cython language and freely mix elements of Python and C, talking to both sides natively
  6. write your code in C and wrap it

So it opens up that entire huge grey area between those two extremes that you get from other tools. It lets you freely choose the tradeoff between simplicity and speed, and makes it very easy to move gradually between one and the other.

Want to reduce complexity and use fast, high-level tools? Use Python constructs. Compiling them in Cython makes them even faster by statically analysing and optimising your code and inferring types for you. And it allows you to give the compiler explicit static type hints that reduce overhead and specialise your code even further.

Want low-level speed? Move closer to C constructs, in exactly those areas in your code that need it. Any point along that gradient is right at your finger tips. Need to talk to C, C++, Fortran, maybe other languages? Without having to go through a level of indirection that bites right into your performance benefit? You can. Cython makes this easy, actually "normal".

And, we're always interested in improving the "static type declarations in Python code" kind of usage (which we call "pure Python mode"), so if you want to help extending the expressiveness of Cython's type declarations for pure Python code to further blur the gradients for users, you should talk to us about it. We have a mailing list.