Commit 0ab91a54 authored by Stefan Behnel's avatar Stefan Behnel

docs: Resolve several exception handling/propagation issues in the examples.

parent af958067
......@@ -2,7 +2,7 @@
# calc_pi.pyx
cdef inline double recip_square(int i):
cdef inline double recip_square(int i) except -1.0:
return 1. / (i * i)
def approx_pi(int n=10000000):
......
......@@ -5,7 +5,7 @@
cimport cython
@cython.profile(False)
cdef inline double recip_square(int i):
cdef inline double recip_square(int i) except -1.0:
return 1. / (i * i)
def approx_pi(int n=10000000):
......
......@@ -8,7 +8,8 @@ cdef Py_ssize_t n = strlen(hello_world)
cdef char* c_call_returning_a_c_string():
cdef char* c_string = <char *> malloc((n + 1) * sizeof(char))
if not c_string:
raise MemoryError()
return NULL # malloc failed
strcpy(c_string, hello_world)
return c_string
......@@ -16,7 +17,7 @@ cdef char* c_call_returning_a_c_string():
cdef void get_a_c_string(char** c_string_ptr, Py_ssize_t *length):
c_string_ptr[0] = <char *> malloc((n + 1) * sizeof(char))
if not c_string_ptr[0]:
raise MemoryError()
return # malloc failed
strcpy(c_string_ptr[0], hello_world)
length[0] = n
......@@ -9,7 +9,7 @@ cdef class Rectangle:
self.y1 = y1
cdef int _area(self):
area = (self.x1 - self.x0) * (self.y1 - self.y0)
cdef int area = (self.x1 - self.x0) * (self.y1 - self.y0)
if area < 0:
area = -area
return area
......
......@@ -8,5 +8,5 @@ cdef:
float a
Spam *p
void f(Spam *s):
void f(Spam *s) except *:
print(s.tons, "Tons of spam")
from cython.parallel import prange
cdef int func(Py_ssize_t n):
cdef int func(Py_ssize_t n) except -1:
cdef Py_ssize_t i
for i in prange(n, nogil=True):
......
......@@ -200,18 +200,21 @@ profile script then at all. The script now outputs the following:
1 0.000 0.000 4.406 4.406 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
We gained 1.8 seconds. Not too shabby. Comparing the output to the previous, we
see that recip_square function got faster while the approx_pi function has not
changed a lot. Let's concentrate on the recip_square function a bit more. First
note, that this function is not to be called from code outside of our module;
so it would be wise to turn it into a cdef to reduce call overhead. We should
also get rid of the power operator: it is turned into a pow(i,2) function call by
Cython, but we could instead just write i*i which could be faster. The
We gained 1.8 seconds. Not too shabby. Comparing the output to the previous, we
see that the ``recip_square()`` function got faster while the ``approx_pi()``
function has not changed a lot. Let's concentrate on the recip_square function
a bit more. First, note that this function is not to be called from code outside
of our module; so it would be wise to turn it into a cdef to reduce call overhead.
We should also get rid of the power operator: it is turned into a pow(i,2) function
call by Cython, but we could instead just write i*i which could be faster. The
whole function is also a good candidate for inlining. Let's look at the
necessary changes for these ideas:
.. literalinclude:: ../../examples/tutorial/profiling_tutorial/calc_pi_3.pyx
Note that the ``except`` declaration is needed in the signature of ``recip_square()``
in order to propagate division by zero errors.
Now running the profile script yields:
.. code-block:: none
......
......@@ -124,6 +124,9 @@ Python variable::
from c_func cimport c_call_returning_a_c_string
cdef char* c_string = c_call_returning_a_c_string()
if c_string is NULL:
... # handle error
cdef bytes py_string = c_string
A type cast to :obj:`object` or :obj:`bytes` will do the same thing::
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment