Cython: Speed up your Python Code

Introduction:

Cython, is a variation of Python which actually was made to act like a superset of Python. Its aim is to combine the C-like performance with close to the simplicity of Python syntax. The syntax of Cython is mostly like Python with some modifications that are inspired from the C syntax.

Cython is a compiled language, unlike Python. It is compiled to generate CPython Extension Modules. Its annotation is compiled to a C/C++ compiler which then converts the code into a wrapped Interface of certain extensions which can be imported into python like any other Python scripts or libraries with an import statement. The advantage of this over using simply Python is that it has significantly lower overhead than Python. Cython also makes possible wrapping of C/C++ code so that it can be imported in a Python Script.

cython-img

Structure of Cython:

Cython works by producing a standard Python module which is compatible with any Python Script. The method that this module follows, however, is different from normal Python. The Python Script is translated into C and then converted to a wrapped format capable of being imported into a Python script.

The Cython code imported into Python is definitely faster than Python. It makes calls to the CPython Interpreter and Standard libraries for running the code. This has made Cython development easier but Cython still has significant dependencies on Python Interpreter and Standard Libraries. The Cython, in short, uses the Interpreters of both Python and C together.

Cython uses CPython Virtual Machine for interpreting the code. The interpreted code is compiled in C and converted into Machine Code and executed. Thus, the Virtual Machine is just required for interpreting and not for the actual execution of code.

Syntactic Differences between Cython and Python:

First of all, Python is dynamically typed language and variables do not need to be initialized in Python. Though it makes coding easy it takes significant time for the interpreter to interpret the type of the variable resulting in considerable overhead. Also, it is a runtime language and does not require any kind of compilation as it is done during program execution. This results in latency during execution.

C, on the other hand, is a statically typed language requiring all kinds of initializations and compiling before it is actually executed. Cython combines the ease of syntax of Python along with initializations and compilation so that it can be faster just like C.

Initialization in Cython:

#Only Python

int = 6

#Only C

cdef int = 6

#C and Python Both

cpdef int = 6

Function Definition in Cython:

#Python Function

def function(Arg1, Arg2………)

#C Function

cdef return_type function(Arg1, Arg2………)

#C and Python Function

cpdef return_type function(Arg1, Arg2………)

Data Type Initialization in Cython mapped with corresponding Python

Cython Python
int int
float float
str str
bint bool
list list

Compiling and Running Cython Script

The Cython Script is saved as .pyx. The sample script may look like below:

Name of file: Cython_Test.pyx

cpdef int test(int x):
cdef int i = 0
cdef int y = 0
for i in range(x):
y += i
return y
test(100)

Next up, a setup.py script is created in the same directory as the Cython Script.

Name of file: setup.py

from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize(“Cython_Test.pyx”)
)

Further, an Ubuntu Terminal is opened and the Cython Script is compiled using the below command:

python3 setup.py build_ext –inplace

After this command is executed, a build folder, a .so file and a C file are generated.The command below also generates a similar output. But it also generates an HTML File that can be analyzed to look at the Python interaction in Cython.

cython -a Cython_Test.pyx

The HTML file in a Browser somewhat looks like below:

cython-snap

A comparison script can be written to find out the difference in performance between Cython and Python.

import python_test
import cython_test
import time
import argparse
import matplotlib.pyplot as plt
parser = argparse.ArgumentParser()
parser.add_argument(“-n”,”–number”, type=int, help=”maximum iterations”,default=100)
args = parser.parse_args()
n = args.number
py = [ ]
cy = [ ]
for i in range(n):
a=time.time()
python_test.test(i)
b=time.time()
c=time.time()
cython_test.test(i)
d=time.time()
py.append(b-a)
cy.append(d-c)
try:
print(“Cython is {} times faster than Python”.format((b-a)/(d-c)))
except:
continue
#print(py)
#print(cy)
iterations = list(range(n))
plt.plot(iterations, py)
plt.plot(iterations, cy)
plt.title(‘Python vs Cython Performance Comparison’)
plt.ylabel(‘execution time’)
plt.xlabel(‘iterations’)
plt.legend([‘python’, ‘cython’], loc=’upper left’)
plt.show()
plt.savefig(‘comparison.png’)

The table shows the performance improvement in Cython as compared to Python:

cython-snap2

If in the above comparison script, the loop is run 10000 times, it gives the following resultant plot:

cython-snap3

After analyzing the above plot it is very evident that Cython is much faster than Python, occupies much lower memory and has significantly lower overhead.

Thank you for reaching out to Wobot.ai. Someone from our team will contact you soon.