Search code examples
functioncythondefinitionfunction-definition

Should I define my Cython function using def, cdef, or cpdef for optimal performance?


How can I know whether to use def, cdef or cpdef when defining a Cython function, assuming I want optimal performance?


Solution

  • If you want optimal performance, you should know that as mentioned in this answer to a related question:

    Once the function has been called there is no difference in the speed that the code inside a cdef and a def function runs at.

    So for optimal Cython performance you should always statically type all arguments and variables, and intuitively you would then be tempted to use cdef, but there are some caveats for which I constructed the flowchart below (also based on previously mentioned answer):

    def, cdef, cpdef flowchart

    Furthermore, note that:

    cpdef functions cause Cython to generate a cdef function (that allows a quick function call from Cython) and a def function (which allows you to call it from Python). Interally the def function just calls the cdef function.

    ... and from the Cython documentation:

    This exploits early binding so that cpdef functions may be as fast as possible when using C fundamental types (by using cdef). cpdef functions use dynamic binding when passed Python objects and this might much slower, perhaps as slow as def declared functions.

    There exists also a case-specific benchmark (calling the function often and from Python) which yields the following result:

    enter image description here