cython

Getting started with cython

Remarks#

What is Cython?

The Cython programming language enriches Python by C-like static typing, the ability to directly call C functions, and several other features. This allows to reach C-level performance while still using a Python-like syntax.

How does it work?

Cython code is compiled using the cython source-to-source compiler to create C or C++ code, which in turn can be compiled using a C compiler. This allows to create extensions that can be imported from Python or executables.

The main performance gain Cython can reach in contrast to pure Python stems from bypassing the CPython API. For example when adding two integers, Python performs a type check for each variable, finds an add function that satisfies the found types, and calls that function. In the Cython-generated C code, the types are already know and only one function call to is made. Hence, Cython especially shines for mathematic problems in which the types are clear.

How do I use it to speed up my code?

A common use case, when trying to speed up a program using Cython, is to profile the code and move the computationally expensive parts to compiled Cython modules. This allows to retain Python syntax for the bulk of the code and apply the speedup where it is most needed.

Installing Cython

To use Cython two things are needed.The Cython package itself, which contains the cython source-to-source compiler and Cython interfaces to several C and Python libraries (for example numpy). To compile the C code generated by the cython compiler, a C compiler is needed.

Step 1: Installing Cython

System Agnostic

Cython can be installed with several system agnostic package management systems. These include:

  1. PyPI via pip or easy_install:

    $ pip install cython
    $ easy_install cython
  2. anaconda using conda:

    $ conda install cython
  3. Enthought canopy using the enpkg package manager:

    $ enpkg cython

Also the source code can be downloaded from github and installed manually using:

$ python setup.py install

Ubuntu, Debian

For Ubuntu the packages cython and cython3 are available. Note that these provide an older version than the installation options mentioned above.

$ apt-get install cython cython3

Windows

For Windows, a .whl file that can be installed using pip is provided by a third party. Details on installing a .whl file on Windows can be found here.


Step 2: Installing a C Compiler

To compile the C files generated by Cython, a compiler for C and C++ is needed. The gcc compiler is recommended and can be installed as follows.

Ubuntu, Debian

The build-essential package contains everything that is needed. It can be installed from the repositories using:

$ sudo apt-get install build-essential

MAC

The XCode developer tools contain a gcc like compiler.

Windows

MinGW (Minimalist GNU for Windows) contains a Windows version of gcc. The compiler from Visual Studio can also be used.

Hello World

A Cython pyx file needs to be translated to C code (cythonized) and compiled before it can be used from Python. A common approach is to create an extension module which is then imported in a Python program.

Code

For this example we create three files:

  • hello.pyx contains the Cython code.
  • test.py is a Python script that uses the hello extension.
  • setup.py is used to compile the Cython code.

hello.pyx

from libc.math cimport pow

cdef double square_and_add (double x):
    """Compute x^2 + x as double.

    This is a cdef function that can be called from within
    a Cython program, but not from Python.
    """
    return pow(x, 2.0) + x

cpdef print_result (double x):
    """This is a cpdef function that can be called from Python."""
    print("({} ^ 2) + {} = {}".format(x, x, square_and_add(x)))

test.py

# Import the extension module hello.
import hello

# Call the print_result method 
hello.print_result(23.0)

setup.py

from distutils.core import Extension, setup
from Cython.Build import cythonize

# define an extension that will be cythonized and compiled
ext = Extension(name="hello", sources=["hello.pyx"])
setup(ext_modules=cythonize(ext))

Compiling

This can be done by, using cython hello.pyx to translate the code to C and then compile it using gcc. An easier way is to let distutils handle this:

$ ls
hello.pyx  setup.py  test.py
$ python setup.py build_ext --inplace
$ ls
build  hello.c  hello.cpython-34m.so  hello.pyx  setup.py  test.py

The shared object (.so) file can be imported and used from Python, so now we can run the test.py:

$ python test.py
(23.0 ^ 2) + 23.0 = 552.0 

This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow