cdef declares Cython-level functions, variables, and typed data so generated code can operate at the C level rather than through Python interfaces. Cython-level annotations differ completely from modern Python annotations. section 5.2.2
Use cdef to reduce Python interaction in performance-critical code:
- Declare scalar variables such as nrows, ncols, and mean with C types, and type NumPy arrays through cimported NumPy definitions. section 5.2.2
- Declare functions with typed returns using cdef; these functions are callable only from Cython and have no Python wrapper. section 5.2.4
- Replace cpdef functions in internal hot paths when Python access is unnecessary, eliminating wrapper and Python-object overhead. section 5.2.4 section 5.4.2
- Combine cdef with typed memoryviews and, after removing Python connections, nogil for code that can support real parallelism. section 5.4.2
Typed internal function
cdef int add4_annotated_cret(int my_number): return my_number + 4 A Python-callable and Cython-callable wrapper can instead use cpdef, while the computational core remains cdef. section 5.2.4
Image-processing optimization
Annotating loop variables, pixel values, arrays, and the output buffer reduces a darkening operation from approximately 30 seconds in native Python to 1.5 seconds. Further removal of Python interactions reaches 0.04 seconds in the described implementation. section 5.2.2 section 5.4.2
#cython: language_level=3
import numpy as np
cimport numpy as cnp #1
def darken_annotated(
cnp.ndarray[cnp.uint8_t, ndim=3] image, #2
cnp.ndarray[cnp.uint8_t, ndim=2] darken_filter): #3
cdef int nrows = image.shape[0] #4
cdef int ncols = image.shape[1]
cdef cnp.uint8_t dark_pixel, mean #5
cdef cnp.ndarray[np.uint8_t] pixel
cdef cnp.ndarray[cnp.uint8_t, ndim=2]
dark_image = np.empty(shape=(nrows, ncols), dtype=np.uint8)
for row in range(nrows):
for col in range(ncols):
pixel = image[row, col]
mean = (pixel[0] + pixel[1] + pixel[2]) // 3 #6
dark_pixel = darken_filter[row, col]
dark_image[row, col] = mean * (255 - dark_pixel) // 255
return dark_image
Inspect the complete typed darkening function, including cimported NumPy types, typed dimensions, scalar declarations, and nested loops. section 5.2.2
@cython.boundscheck(False) #1
cdef void darken_annotated_mv( #2
cnp.uint8_t[:,:,:] image_mv,
cnp.uint8_t[:,:] darken_filter_mv,
cnp.uint8_t[:,:] dark_image_mv) nogil: #3
Inspect the internal cdef function signature using typed memoryviews and nogil after Python-facing operations have been removed. section 5.4.2
