code: def do_cprofile(func):
      
      def profiled_func(*args, **kwargs):
          profile = cProfile.Profile()
          try:
              profile.enable()
              result = func(*args, **kwargs)
              profile.disable()
              return result
          finally:
              profile.print_stats()
      return profiled_func
docs: Decorator to profile a function
  
      It gives good numbers on various function calls but it omits a vital piece
      of information: what is it about a function that makes it so slow?
  
      However, it is a great start to basic profiling. Sometimes it can even
      point you to the solution with very little fuss. I often use it as a
      gut check to start the debugging process before I dig deeper into the
      specific functions that are either slow are called way too often.
  
      Pros:
      No external dependencies and quite fast. Useful for quick high-level
      checks.
  
      Cons:
      Rather limited information that usually requires deeper debugging; reports
      are a bit unintuitive, especially for complex codebases.
  
      See also
      --------
      do_profile, test_do_profile