https://cython.readthedocs.io/en/latest/index.html
Cython is Python with C data types.
Usually the speedups are between 2x to 1000x. It depends on how much you call the Python interpreter
*.pyx - something similar to C/C++ source files
*.pxd - something similar to C-header files. PXD files are imported into PYX files with cimport keyword
Almost any piece of Python code is also valid Cython code.
Cython’s two major use cases:
1. Extending the CPython interpreter with fast binary modules
2. Interfacing Python code with external C libraries.
def-functions - Python functions are defined using the def statement, as in Python. Only Python functions can be called from outside the module by interpreted Python code.
cdef-functions - C functions are defined using the new cdef statement. Within a Cython module, Python functions and C functions can call each other freely.
cpdef-functions - is hybrid of cdef and def. It uses the faster C calling conventions when being called from other Cython code. And this function can be called from Python too.
During passing argument from cdef to def functions and vice versa there is an automatic type casting:
1. The cdef statement is used to declare C variables, either local or module level
cdef int i, j, k
2. With cdef you can declare structs, union, enums
cdef struct Grail: int age float volume
3. You can use ctypedef as equivalent for typedef
ctypedef unsigned long ULong
4. It's possible declare functions with cdef, making them c functions.
cdef int eggs(unsigned long l, float f)
build.bat
python setup.py build_ext --inplace :: Output of this command is:: helloworld.so in Unix like OS :: helloworld.pyd in Windows :: Alternative to launch build is using :: pyximport via "import pyximport; pyximport.install()"
setup.py
from setuptools import setup from Cython.Build import cythonize setup( name = 'Hello world app', ext_modules = cythonize("*.pyx"), zip_safe = False,)
hello.pyx
import time def timing(f): def wrap(*args): time1 = time.time() ret = f(*args) time2 = time.time() print('{:s} function took {:.3f} ms'.format(f.__name__, (time2-time1)*1000.0)) return ret return wrap def say_hello_to(name): print("Hello %s!" % name)def f(double x): return x ** 2 - x @timing def integrate_f(double a, double b, int N): cdef int i cdef double s, dx s = 0 dx = (b - a) / N for i in range(N): s += f(a + i * dx) return s * dx @timing def integrate_f_std(a, b, N): s = 0 dx = (b - a) / N for i in range(N): s += f(a + i * dx) return s * dx
External declaration
cdef extern from "math.h": double sin(double x)
1. This declares the sin() function in a way that makes it available to Cython code.
2. Instructs Cython to generate C code that includes the math.h header file.
3. The C compiler will see the original declaration in math.h at compile time.
4. Cython does not parse “math.h” and requires a separate definition
5. it is possible to declare and call into any C library as long as the module that Cython generates is properly linked against the shared or static library.
Call C Standart Library function from Cython
from libc.math cimport sincdef double f(double x): return sin(x * x)
To test at C compilation time which CPython version your code is being compiled with
from cpython.version cimport PY_VERSION_HEXprint(PY_VERSION_HEX >= 0x030200F0)