#!/usr/bin/env python # coding: utf-8 # MIKE'S NOTE: # This doesn't seem to work anymore. This is widely linked to as a very popular post on StackOverflow # (https://stackoverflow.com/questions/28301931/how-to-profile-cython-functions-line-by-line) # but something seems to have broken since it was posted (2015, now 2023). # # This notebook demonstrates the use of Robert Kern's `line_profiler` (https://github.com/rkern/line_profiler) to profile `cython` functions line by line. Thanks to Robert Bradshaw for implementing this feature (https://groups.google.com/forum/#!topic/cython-users/FH3TYK8BkeA). # In[1]: #Load Robert Kern's line profiler get_ipython().run_line_magic('load_ext', 'line_profiler') import line_profiler # In[2]: # Mike's note: this updated cell is from the accompanying StackOverflow post: # https://stackoverflow.com/questions/28301931/how-to-profile-cython-functions-line-by-line # Thanks to @tryptofame for proposing an updated snippet from Cython.Compiler.Options import get_directive_defaults directive_defaults = get_directive_defaults() directive_defaults['linetrace'] = True directive_defaults['binding'] = True # Mike's note: also added this, as suggested later in the thread, but doesn't do much directive_defaults['profile'] = True # In[3]: # Mike's note: also added this get_ipython().run_line_magic('load_ext', 'cython') # In[4]: get_ipython().run_cell_magic('cython', '-a -f --compile-args=-DCYTHON_TRACE_NOGIL=1', "# Mike's note: It was also suggested in the above thread to change CYTHON_TRACE_NOGIL to just CYTHON_TRACE\n# Doesn't seem to make a difference either way.\n#We need to define the macro CYTHON_TRACE=1 (cf. http://docs.cython.org/src/reference/compilation.html)\n\ndef cumulative_sum(int n):\n cdef int s=0, i\n for i in range(n):\n s += i\n \n return s\n") # In[5]: #Print profiling statistics using the `line_profiler` API profile = line_profiler.LineProfiler(cumulative_sum) profile.runcall(cumulative_sum, 100) profile.print_stats() # Mike's note: # On at least two computers, both macOS, one a newer M1 running Monterey and one an old Intel running High Sierra # doesn't work either way. # This is running line_profiler 4.0.2, and have tested both from pip # and building directly from this commit (the latest as of this writing): # https://github.com/pyutils/line_profiler/commit/6ee9f63d7a0b4cbec55e58f02462cdd08f9884e0 # And cython 0.29.33. # Timer unit: 1e-09 s # In[6]: #Print profiling statistics using the `lprun` magic # Mike's note: same as above. get_ipython().run_line_magic('lprun', '-f cumulative_sum cumulative_sum(100)') # In[ ]: