Variables

In Cython, you can declare the type of a variable by prepending the variable with cdef and its respective type. For example, we can declare the i variable as a 16 bit integer in the following way:

    cdef int i 

The cdef statement supports multiple variable names on the same line along with optional initialization, as seen in the following line:

    cdef double a, b = 2.0, c = 3.0 

Typed variables are treated differently in comparison to regular variables. In Python, variables are often described as labels that refer to objects in memory. For example, we could assign the value 'hello' to the a variable at any point in the program without restriction:

    a = 'hello' 

The a variable holds a reference to the 'hello' string. We can also freely assign another value (for example, the integer 1) to the same variable later in the code:

    a = 1 

Python will assign the integer 1 to the a variable without any problem.

Typed variables behave quite differently and are usually described as data containers: we can only store values that fit into the container that is determined by its data type. For example, if we declare the a variable as int, and then we try to assign it to a double, Cython will trigger an error, as shown in the following code:

    %%cython 
cdef int i
i = 3.0

# Output has been cut
...cf4b.pyx:2:4 Cannot assign type 'double' to 'int'

Static typing makes it easy for the compiler to perform useful optimizations. For example, if we declare a loop index as int, Cython will rewrite the loop in pure C without needing to step into the Python interpreter. The typing declaration guarantees that the type of the index will always be int and cannot be overwritten at runtime so that the compiler is free to perform the optimizations without compromising the program correctness.

We can assess the speed gain in this case with a small test case. In the following example, we implement a simple loop that increments a variable 100 times. With Cython, the example function can be coded as follows:

    %%cython 
def example():
cdef int i, j=0
for i in range(100):
j += 1
return j

example()
# Result:
# 100

We can compare the speed of an analogous, untyped, pure Python loop:

    def example_python(): 
j=0
for i in range(100):
j += 1
return j

%timeit example()
10000000 loops, best of 3: 25 ns per loop
%timeit example_python()
100000 loops, best of 3: 2.74 us per loop

The speedup obtained by implementing this simple type declaration is a whopping 100x! This works because the Cython loop has first been converted to pure C and then to efficient machine code, while the Python loop still relies on the slow interpreter.

In Cython, it is possible to declare a variable to be of any standard C type, and it is also possible to define custom types using classic C constructs, such as struct, enum, and typedef.

An interesting example is that if we declare a variable to be of the object type, the variable will accept any kind of Python object:

    cdef object a_py 
# both 'hello' and 1 are Python objects
a_py = 'hello'
a_py = 1

Note that declaring a variable as object has no performance benefits as accessing and operating on the object will still require the interpreter to look up the underlying type of the variable and its attributes and methods.

Sometimes, certain data types (such as float and int numbers) are compatible in the sense that they can be converted into each other. In Cython, it is possible to convert (cast) between types by surrounding the destination type between pointy brackets, as shown in the following snippet:

    cdef int a = 0 
cdef double b
b = <double> a
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.93.20