How to use Cython compiler??
Introduction
There are two terms which could be interchangeably confused: Cython and CPython.
Cython is a compiled language which can be regarded as a superset of Python. The compiler translates the input Cython/Python code to a portable C code. Which in-turn could be compiled with a GCC compiler to get an executable. Cython helps to make a python program run faster. Whereas CPython implies that its the C language implementation of python interpreter. There are other versions of python as well like Jython(Java implementation), IronPython(C# implementation) etc.
Say for example, let us consider a sample program. Refer to the description given for more information.
When the sample.py is run, the running time is recored as given below:
0.004858970642089844, 0.004592180252075195, 0.004554033279418945, 0.00444793701171875
For working with Cython initially we have to convert the python/Cython code into C language. It can be done using the Cython compiler.
Output will be a C source file named sample.c
NOTE:
If the option --embed[=<method_name>]
is not given along with cython command, a main function is not included in
the resulting code
After the compilation step, we have two ways to proceed:
-
Make a shared library and use it as a python extension module(used as a library).
-
Make a binary file which could be executed a highier speed(if it has an input output style code)
Make a module
Note the use of .so extension for the output shared library. The file sample.so can be imported as a regular python module by the name sample. If a python program by the same name is present in the same directory, then the python file will only get imported. Recorded running time for module imported from shared library:
0.015142202377319336, 0.014052867889404297, 0.012368202209472656, 0.01092982292175293
Recorded running time for module imported from python script:
0.00722503662109375, 0.00661015510559082, 0.006145954132080078, 0.0056989192962646484
Make an executable
This is just a regular gcc compilation with the header file location mentioned using -I flag.
After compiling with cython and running the resultant C program, the recored times for five trials are as follows:
0.002379894256591797, 0.0022690296173095703, 0.0022478103637695312, 0.002251863479614258
The running time has doubled after running using the cython generated code.
Other flags such as -lpthread, -Os, -lm, -lutil, -ldl can be used as optional as per your requirement.
Command | Purpose | |
---|---|---|
-Os | Optimize size | |
-lpython2.7 | Include python2.7 libraries | |
-lpthread | Include pthread libraries | |
-lm | ||
-lutil | ||
-ldl |
All the library dependency can be seen using ldd command
FAQ:
Quest: Why do I get this import error? “ImportError: ./sample.so: cannot dynamically load executable”
Ans: You are trying to import a file which is not a shared library. Use -shared flag along with gcc
Quest: What is the error init function not defined? “ImportError: dynamic module does not define init function (initsample_test)”
Ans: Names of the files, ie the shared library and both input codes(C and python/cython) has to be
same with only the extensions changed.
Interesting Links:
Stackoverflow - A stackoverflow question similar to our topic.
Presentation by Dr.Stefan Behnel.
Tutorial on shared libraries.
NOTE:
This article do not contain on how to wite a Cython code. This link will help you learn some Cython code.