Cython-A Speed-Up Tool for your Python Function
By: Khuyen Tran
Tags: Numpy, Data Science, Python, C, Cython

Cython-A Speed-Up Tool for your Python Function

Motivation

If you read my article on how to create your own Matrix module from scratch with Python, you might want to create your own matrix class with your own algorithms. That is a great idea since you will have the flexibility to create the module of your preference. But you may want to understand the difference between Numpy and your Python Matrix class before creating a function with the multi-dimensional arrays.

Retrieved from Idle Coding

You Create a Function for a Matrix. Let’s Test it out

Let’s start with an example to help you understand the difference between Numpy and your module created with Python.

We expect the matrix multiplication using Numpy will give the same result as the first one. Let’s see if they give the same results on the same matrix dimensions.

Create multiple matrices with different dimensions:

nump= []

mult=[]

for i in range(0,500,100): nump.append(calculate(npAB,(i,i))) mult.append(calculate(mulAB,(i,i)))

Performance between Python implementation and Numpy. Find the implementation here

We created matrices with dimension 100x100, 200x200, …, 500x500. We can see that the amount of time for our Python function increases exponentially with the increase in dimension while Numpy could complete the calculation within seconds. How could Numpy perform so much better than our Python implementation if it is also a Python library?

Numpy — Not Quite a Python Library

Numpy integrates C/C++ and Fortran code to provide a high-performance when working with multi-dimensional arrays instead of using pure Python.

If you don’t know the difference between C and Python, C is compiled language and Python is interpreted language. While variables are declared in C, variables are not declared in Python. This makes Python easier to write but also comes with the cost that Python needs to interpret the variables each time the code is executed. Thus, Python runs much slower than C when it comes to a multi-dimensional array.

What if there is a language that enables you to use Python syntax while achieving C performance? Cython helps you to do exactly that.

Introduction to Cython

Cython is an optimising static compiler for both Python and the extended Cython. The great thing about this is that it makes the syntax writing C extension as easy as Python itself. Cython combines the advantage of Python and C to let you interact efficiently with large data sets. As Cython drops down the code to the machine level, it speeds up the execution of Python code. You could find the Cython documentation here.

The compiled extension of Cython involves three files:

Main file

The function to be compiled in .pyx file

file A setup.py contains the instructions to make the extension module

Create Function File with Cython

Create a file called mult_fast.pyx . The .pyx extension is for Cython file

We could easily tune Python code into plain C performance by adding static type declarations in readable Python syntax. This could be done simply by cdef type name = value . Also, don’t forget to declare the variables in the function’s parameters.

def mulAB( double[:,:] A , double[:,:] B):

cdef int Am = A.shape[0]

cdef int An = A.shape[1]

cdef int Bm = B.shape[0]

cdef int Bn = B.shape[1] cdef int i = 0

cdef int j = 0

cdef int k = 0 cdef double temp = 0.0 cdef double[:,:] C = np.empty((Am,Bn), dtype=np.double)

After declaring the variables in our code, we start the next line with nogil. Now you just need to copy and paste the function you created previously here:

with nogil:

for i in range(Am):

for j in range(Bn):

temp=0.0

for k in range(An):

temp += A[i,k] * B[k,j]

C[i,j] = temp



return np.array(C)

Put everything together:

mult_fast.pyx file

Set Up

Save this file as setup.py .

setup.py

You could copy and paste this setup.py file for your future Cython file. The only thing that you need to change is the name of the file in the extensions and setup ( mult_fast & [“mult_fast.pyx”] ).

On the command line, type:

python3 setup.py build_ext --inplace

Last Touch with Main.py file

Import mult_fast.py and write the main02.py file

Ready? Let’s Launch

We can see that Cython performs as nearly as good as Numpy. You may not choose to use Cython in a small dataset, but when working with a large dataset, it is worthy for your effort to use Cython to do our calculation quickly

Conclusion

With a little bit of fixing in our Python code to utilize Cython, we have made our function run much faster. I hope this article gives you the ideas to create your own module in a more efficient way. Feel free to fork and play with the code for this article in this Github repo.

I like to write about basic data science concepts and play with different algorithms and data science tools. You could connect with me on LinkedIn and Twitter.

Star this repo if you want to check out the codes for all of the articles I have written. Follow me on Medium to stay informed with my latest data science articles like these: