## Thursday, December 23, 2010

### Cython 2

I've been puzzling over the Cython docs and tutorial for quite a few hours now, trying to write a simple C function (in a .c file) and compile and call it from Cython. Like the example from before (here), except using my own function rather than a C math library call. I can't figure it out, so I posted questions on Stack Overflow and the Cython users list. While I'm taking a break I decided to play a bit with Fibonacci numbers.

The setup is simple: in `cy.pyx` (see below) we have two alternative implementations that compute the Nth element of the Fibonacci series. One version has Cython declarations that the variables are ints (and one for the function itself). The second version is plain Python. In a simple Python script `cy.py` we do

 `import pyximportpyximport.install()import cydef f(N): cy.cyfib(N)def g(N): cy.pyfib(N)`

This translates the Python to C, builds it, and makes it accessible from within Python. We have to "wrap" the functions in Python calls in order to use `timeit` (at least, that's how I did it). Then we go to the command line and compare:

 `\$ python -m timeit -s 'import cypy' 'cypy.f(1000)'1000000 loops, best of 3: 1.37 usec per loop\$ python -m timeit -s 'import cypy' 'cypy.g(1000)'1000 loops, best of 3: 232 usec per loop`

The Cython version is quite a bit faster! Curiously cdef'ing the temp variable slows the timing down by a factor of 10. Hmm..

[UPDATE: There are issues!

 `>>> cy.cyfib(10)55>>> cy.cyfib(100)-980107325>>> cy.pyfib(100)354224848179261915075LI edit to use double instead of int:>>> cy.cyfib(100)3.54224848179262e+20>>> cy.pyfib(100)354224848179261915075LIt's rounded, but at least it's not negative!`

]

 `import numpycpdef cyfib(int N): cdef int a cdef int b cdef int counter a = 1 b = 1 counter = 2 #cdef temp while counter < N: temp = a + b a = b b = temp counter += 1 return bdef pyfib(N): a,b = 1,1 counter = 2 while counter < N: temp = a + b a = b b = temp counter += 1 return b`