17db96d56Sopenharmony_ci.. _profile:
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci********************
47db96d56Sopenharmony_ciThe Python Profilers
57db96d56Sopenharmony_ci********************
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci**Source code:** :source:`Lib/profile.py` and :source:`Lib/pstats.py`
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci--------------
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci.. _profiler-introduction:
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciIntroduction to the profilers
147db96d56Sopenharmony_ci=============================
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci.. index::
177db96d56Sopenharmony_ci   single: deterministic profiling
187db96d56Sopenharmony_ci   single: profiling, deterministic
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci:mod:`cProfile` and :mod:`profile` provide :dfn:`deterministic profiling` of
217db96d56Sopenharmony_ciPython programs. A :dfn:`profile` is a set of statistics that describes how
227db96d56Sopenharmony_cioften and for how long various parts of the program executed. These statistics
237db96d56Sopenharmony_cican be formatted into reports via the :mod:`pstats` module.
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ciThe Python standard library provides two different implementations of the same
267db96d56Sopenharmony_ciprofiling interface:
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ci1. :mod:`cProfile` is recommended for most users; it's a C extension with
297db96d56Sopenharmony_ci   reasonable overhead that makes it suitable for profiling long-running
307db96d56Sopenharmony_ci   programs.  Based on :mod:`lsprof`, contributed by Brett Rosen and Ted
317db96d56Sopenharmony_ci   Czotter.
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci2. :mod:`profile`, a pure Python module whose interface is imitated by
347db96d56Sopenharmony_ci   :mod:`cProfile`, but which adds significant overhead to profiled programs.
357db96d56Sopenharmony_ci   If you're trying to extend the profiler in some way, the task might be easier
367db96d56Sopenharmony_ci   with this module.  Originally designed and written by Jim Roskind.
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_ci.. note::
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci   The profiler modules are designed to provide an execution profile for a given
417db96d56Sopenharmony_ci   program, not for benchmarking purposes (for that, there is :mod:`timeit` for
427db96d56Sopenharmony_ci   reasonably accurate results).  This particularly applies to benchmarking
437db96d56Sopenharmony_ci   Python code against C code: the profilers introduce overhead for Python code,
447db96d56Sopenharmony_ci   but not for C-level functions, and so the C code would seem faster than any
457db96d56Sopenharmony_ci   Python one.
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ci.. _profile-instant:
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ciInstant User's Manual
517db96d56Sopenharmony_ci=====================
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ciThis section is provided for users that "don't want to read the manual." It
547db96d56Sopenharmony_ciprovides a very brief overview, and allows a user to rapidly perform profiling
557db96d56Sopenharmony_cion an existing application.
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ciTo profile a function that takes a single argument, you can do::
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci   import cProfile
607db96d56Sopenharmony_ci   import re
617db96d56Sopenharmony_ci   cProfile.run('re.compile("foo|bar")')
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci(Use :mod:`profile` instead of :mod:`cProfile` if the latter is not available on
647db96d56Sopenharmony_ciyour system.)
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ciThe above action would run :func:`re.compile` and print profile results like
677db96d56Sopenharmony_cithe following::
687db96d56Sopenharmony_ci
697db96d56Sopenharmony_ci         214 function calls (207 primitive calls) in 0.002 seconds
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci   Ordered by: cumulative time
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
747db96d56Sopenharmony_ci        1    0.000    0.000    0.002    0.002 {built-in method builtins.exec}
757db96d56Sopenharmony_ci        1    0.000    0.000    0.001    0.001 <string>:1(<module>)
767db96d56Sopenharmony_ci        1    0.000    0.000    0.001    0.001 __init__.py:250(compile)
777db96d56Sopenharmony_ci        1    0.000    0.000    0.001    0.001 __init__.py:289(_compile)
787db96d56Sopenharmony_ci        1    0.000    0.000    0.000    0.000 _compiler.py:759(compile)
797db96d56Sopenharmony_ci        1    0.000    0.000    0.000    0.000 _parser.py:937(parse)
807db96d56Sopenharmony_ci        1    0.000    0.000    0.000    0.000 _compiler.py:598(_code)
817db96d56Sopenharmony_ci        1    0.000    0.000    0.000    0.000 _parser.py:435(_parse_sub)
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ciThe first line indicates that 214 calls were monitored.  Of those calls, 207
847db96d56Sopenharmony_ciwere :dfn:`primitive`, meaning that the call was not induced via recursion. The
857db96d56Sopenharmony_cinext line: ``Ordered by: cumulative time``, indicates that the text string in the
867db96d56Sopenharmony_cifar right column was used to sort the output. The column headings include:
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_cincalls
897db96d56Sopenharmony_ci   for the number of calls.
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_citottime
927db96d56Sopenharmony_ci   for the total time spent in the given function (and excluding time made in
937db96d56Sopenharmony_ci   calls to sub-functions)
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_cipercall
967db96d56Sopenharmony_ci   is the quotient of ``tottime`` divided by ``ncalls``
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_cicumtime
997db96d56Sopenharmony_ci   is the cumulative time spent in this and all subfunctions (from invocation
1007db96d56Sopenharmony_ci   till exit). This figure is accurate *even* for recursive functions.
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_cipercall
1037db96d56Sopenharmony_ci   is the quotient of ``cumtime`` divided by primitive calls
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_cifilename:lineno(function)
1067db96d56Sopenharmony_ci   provides the respective data of each function
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ciWhen there are two numbers in the first column (for example ``3/1``), it means
1097db96d56Sopenharmony_cithat the function recursed.  The second value is the number of primitive calls
1107db96d56Sopenharmony_ciand the former is the total number of calls.  Note that when the function does
1117db96d56Sopenharmony_cinot recurse, these two values are the same, and only the single figure is
1127db96d56Sopenharmony_ciprinted.
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ciInstead of printing the output at the end of the profile run, you can save the
1157db96d56Sopenharmony_ciresults to a file by specifying a filename to the :func:`run` function::
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_ci   import cProfile
1187db96d56Sopenharmony_ci   import re
1197db96d56Sopenharmony_ci   cProfile.run('re.compile("foo|bar")', 'restats')
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ciThe :class:`pstats.Stats` class reads profile results from a file and formats
1227db96d56Sopenharmony_cithem in various ways.
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_ciThe files :mod:`cProfile` and :mod:`profile` can also be invoked as a script to
1257db96d56Sopenharmony_ciprofile another script.  For example::
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci   python -m cProfile [-o output_file] [-s sort_order] (-m module | myscript.py)
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_ci``-o`` writes the profile results to a file instead of to stdout
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci``-s`` specifies one of the :func:`~pstats.Stats.sort_stats` sort values to sort
1327db96d56Sopenharmony_cithe output by. This only applies when ``-o`` is not supplied.
1337db96d56Sopenharmony_ci
1347db96d56Sopenharmony_ci``-m`` specifies that a module is being profiled instead of a script.
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ci   .. versionadded:: 3.7
1377db96d56Sopenharmony_ci      Added the ``-m`` option to :mod:`cProfile`.
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci   .. versionadded:: 3.8
1407db96d56Sopenharmony_ci      Added the ``-m`` option to :mod:`profile`.
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ciThe :mod:`pstats` module's :class:`~pstats.Stats` class has a variety of methods
1437db96d56Sopenharmony_cifor manipulating and printing the data saved into a profile results file::
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ci   import pstats
1467db96d56Sopenharmony_ci   from pstats import SortKey
1477db96d56Sopenharmony_ci   p = pstats.Stats('restats')
1487db96d56Sopenharmony_ci   p.strip_dirs().sort_stats(-1).print_stats()
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_ciThe :meth:`~pstats.Stats.strip_dirs` method removed the extraneous path from all
1517db96d56Sopenharmony_cithe module names. The :meth:`~pstats.Stats.sort_stats` method sorted all the
1527db96d56Sopenharmony_cientries according to the standard module/line/name string that is printed. The
1537db96d56Sopenharmony_ci:meth:`~pstats.Stats.print_stats` method printed out all the statistics.  You
1547db96d56Sopenharmony_cimight try the following sort calls::
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ci   p.sort_stats(SortKey.NAME)
1577db96d56Sopenharmony_ci   p.print_stats()
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_ciThe first call will actually sort the list by function name, and the second call
1607db96d56Sopenharmony_ciwill print out the statistics.  The following are some interesting calls to
1617db96d56Sopenharmony_ciexperiment with::
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci   p.sort_stats(SortKey.CUMULATIVE).print_stats(10)
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ciThis sorts the profile by cumulative time in a function, and then only prints
1667db96d56Sopenharmony_cithe ten most significant lines.  If you want to understand what algorithms are
1677db96d56Sopenharmony_citaking time, the above line is what you would use.
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ciIf you were looking to see what functions were looping a lot, and taking a lot
1707db96d56Sopenharmony_ciof time, you would do::
1717db96d56Sopenharmony_ci
1727db96d56Sopenharmony_ci   p.sort_stats(SortKey.TIME).print_stats(10)
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_cito sort according to time spent within each function, and then print the
1757db96d56Sopenharmony_cistatistics for the top ten functions.
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ciYou might also try::
1787db96d56Sopenharmony_ci
1797db96d56Sopenharmony_ci   p.sort_stats(SortKey.FILENAME).print_stats('__init__')
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_ciThis will sort all the statistics by file name, and then print out statistics
1827db96d56Sopenharmony_cifor only the class init methods (since they are spelled with ``__init__`` in
1837db96d56Sopenharmony_cithem).  As one final example, you could try::
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_ci   p.sort_stats(SortKey.TIME, SortKey.CUMULATIVE).print_stats(.5, 'init')
1867db96d56Sopenharmony_ci
1877db96d56Sopenharmony_ciThis line sorts statistics with a primary key of time, and a secondary key of
1887db96d56Sopenharmony_cicumulative time, and then prints out some of the statistics. To be specific, the
1897db96d56Sopenharmony_cilist is first culled down to 50% (re: ``.5``) of its original size, then only
1907db96d56Sopenharmony_cilines containing ``init`` are maintained, and that sub-sub-list is printed.
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ciIf you wondered what functions called the above functions, you could now (``p``
1937db96d56Sopenharmony_ciis still sorted according to the last criteria) do::
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_ci   p.print_callers(.5, 'init')
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ciand you would get a list of callers for each of the listed functions.
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ciIf you want more functionality, you're going to have to read the manual, or
2007db96d56Sopenharmony_ciguess what the following functions do::
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci   p.print_callees()
2037db96d56Sopenharmony_ci   p.add('restats')
2047db96d56Sopenharmony_ci
2057db96d56Sopenharmony_ciInvoked as a script, the :mod:`pstats` module is a statistics browser for
2067db96d56Sopenharmony_cireading and examining profile dumps.  It has a simple line-oriented interface
2077db96d56Sopenharmony_ci(implemented using :mod:`cmd`) and interactive help.
2087db96d56Sopenharmony_ci
2097db96d56Sopenharmony_ci:mod:`profile` and :mod:`cProfile` Module Reference
2107db96d56Sopenharmony_ci=======================================================
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci.. module:: cProfile
2137db96d56Sopenharmony_ci.. module:: profile
2147db96d56Sopenharmony_ci   :synopsis: Python source profiler.
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_ciBoth the :mod:`profile` and :mod:`cProfile` modules provide the following
2177db96d56Sopenharmony_cifunctions:
2187db96d56Sopenharmony_ci
2197db96d56Sopenharmony_ci.. function:: run(command, filename=None, sort=-1)
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_ci   This function takes a single argument that can be passed to the :func:`exec`
2227db96d56Sopenharmony_ci   function, and an optional file name.  In all cases this routine executes::
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci      exec(command, __main__.__dict__, __main__.__dict__)
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ci   and gathers profiling statistics from the execution. If no file name is
2277db96d56Sopenharmony_ci   present, then this function automatically creates a :class:`~pstats.Stats`
2287db96d56Sopenharmony_ci   instance and prints a simple profiling report. If the sort value is specified,
2297db96d56Sopenharmony_ci   it is passed to this :class:`~pstats.Stats` instance to control how the
2307db96d56Sopenharmony_ci   results are sorted.
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_ci.. function:: runctx(command, globals, locals, filename=None, sort=-1)
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ci   This function is similar to :func:`run`, with added arguments to supply the
2357db96d56Sopenharmony_ci   globals and locals dictionaries for the *command* string. This routine
2367db96d56Sopenharmony_ci   executes::
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_ci      exec(command, globals, locals)
2397db96d56Sopenharmony_ci
2407db96d56Sopenharmony_ci   and gathers profiling statistics as in the :func:`run` function above.
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ci.. class:: Profile(timer=None, timeunit=0.0, subcalls=True, builtins=True)
2437db96d56Sopenharmony_ci
2447db96d56Sopenharmony_ci   This class is normally only used if more precise control over profiling is
2457db96d56Sopenharmony_ci   needed than what the :func:`cProfile.run` function provides.
2467db96d56Sopenharmony_ci
2477db96d56Sopenharmony_ci   A custom timer can be supplied for measuring how long code takes to run via
2487db96d56Sopenharmony_ci   the *timer* argument. This must be a function that returns a single number
2497db96d56Sopenharmony_ci   representing the current time. If the number is an integer, the *timeunit*
2507db96d56Sopenharmony_ci   specifies a multiplier that specifies the duration of each unit of time. For
2517db96d56Sopenharmony_ci   example, if the timer returns times measured in thousands of seconds, the
2527db96d56Sopenharmony_ci   time unit would be ``.001``.
2537db96d56Sopenharmony_ci
2547db96d56Sopenharmony_ci   Directly using the :class:`Profile` class allows formatting profile results
2557db96d56Sopenharmony_ci   without writing the profile data to a file::
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_ci      import cProfile, pstats, io
2587db96d56Sopenharmony_ci      from pstats import SortKey
2597db96d56Sopenharmony_ci      pr = cProfile.Profile()
2607db96d56Sopenharmony_ci      pr.enable()
2617db96d56Sopenharmony_ci      # ... do something ...
2627db96d56Sopenharmony_ci      pr.disable()
2637db96d56Sopenharmony_ci      s = io.StringIO()
2647db96d56Sopenharmony_ci      sortby = SortKey.CUMULATIVE
2657db96d56Sopenharmony_ci      ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
2667db96d56Sopenharmony_ci      ps.print_stats()
2677db96d56Sopenharmony_ci      print(s.getvalue())
2687db96d56Sopenharmony_ci
2697db96d56Sopenharmony_ci   The :class:`Profile` class can also be used as a context manager (supported
2707db96d56Sopenharmony_ci   only in :mod:`cProfile` module. see :ref:`typecontextmanager`)::
2717db96d56Sopenharmony_ci
2727db96d56Sopenharmony_ci      import cProfile
2737db96d56Sopenharmony_ci
2747db96d56Sopenharmony_ci      with cProfile.Profile() as pr:
2757db96d56Sopenharmony_ci          # ... do something ...
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_ci          pr.print_stats()
2787db96d56Sopenharmony_ci
2797db96d56Sopenharmony_ci   .. versionchanged:: 3.8
2807db96d56Sopenharmony_ci      Added context manager support.
2817db96d56Sopenharmony_ci
2827db96d56Sopenharmony_ci   .. method:: enable()
2837db96d56Sopenharmony_ci
2847db96d56Sopenharmony_ci      Start collecting profiling data. Only in :mod:`cProfile`.
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci   .. method:: disable()
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci      Stop collecting profiling data. Only in :mod:`cProfile`.
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci   .. method:: create_stats()
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci      Stop collecting profiling data and record the results internally
2937db96d56Sopenharmony_ci      as the current profile.
2947db96d56Sopenharmony_ci
2957db96d56Sopenharmony_ci   .. method:: print_stats(sort=-1)
2967db96d56Sopenharmony_ci
2977db96d56Sopenharmony_ci      Create a :class:`~pstats.Stats` object based on the current
2987db96d56Sopenharmony_ci      profile and print the results to stdout.
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_ci   .. method:: dump_stats(filename)
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_ci      Write the results of the current profile to *filename*.
3037db96d56Sopenharmony_ci
3047db96d56Sopenharmony_ci   .. method:: run(cmd)
3057db96d56Sopenharmony_ci
3067db96d56Sopenharmony_ci      Profile the cmd via :func:`exec`.
3077db96d56Sopenharmony_ci
3087db96d56Sopenharmony_ci   .. method:: runctx(cmd, globals, locals)
3097db96d56Sopenharmony_ci
3107db96d56Sopenharmony_ci      Profile the cmd via :func:`exec` with the specified global and
3117db96d56Sopenharmony_ci      local environment.
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ci   .. method:: runcall(func, /, *args, **kwargs)
3147db96d56Sopenharmony_ci
3157db96d56Sopenharmony_ci      Profile ``func(*args, **kwargs)``
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_ciNote that profiling will only work if the called command/function actually
3187db96d56Sopenharmony_cireturns.  If the interpreter is terminated (e.g. via a :func:`sys.exit` call
3197db96d56Sopenharmony_ciduring the called command/function execution) no profiling results will be
3207db96d56Sopenharmony_ciprinted.
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ci.. _profile-stats:
3237db96d56Sopenharmony_ci
3247db96d56Sopenharmony_ciThe :class:`Stats` Class
3257db96d56Sopenharmony_ci========================
3267db96d56Sopenharmony_ci
3277db96d56Sopenharmony_ciAnalysis of the profiler data is done using the :class:`~pstats.Stats` class.
3287db96d56Sopenharmony_ci
3297db96d56Sopenharmony_ci.. module:: pstats
3307db96d56Sopenharmony_ci   :synopsis: Statistics object for use with the profiler.
3317db96d56Sopenharmony_ci
3327db96d56Sopenharmony_ci.. class:: Stats(*filenames or profile, stream=sys.stdout)
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_ci   This class constructor creates an instance of a "statistics object" from a
3357db96d56Sopenharmony_ci   *filename* (or list of filenames) or from a :class:`Profile` instance. Output
3367db96d56Sopenharmony_ci   will be printed to the stream specified by *stream*.
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_ci   The file selected by the above constructor must have been created by the
3397db96d56Sopenharmony_ci   corresponding version of :mod:`profile` or :mod:`cProfile`.  To be specific,
3407db96d56Sopenharmony_ci   there is *no* file compatibility guaranteed with future versions of this
3417db96d56Sopenharmony_ci   profiler, and there is no compatibility with files produced by other
3427db96d56Sopenharmony_ci   profilers, or the same profiler run on a different operating system.  If
3437db96d56Sopenharmony_ci   several files are provided, all the statistics for identical functions will
3447db96d56Sopenharmony_ci   be coalesced, so that an overall view of several processes can be considered
3457db96d56Sopenharmony_ci   in a single report.  If additional files need to be combined with data in an
3467db96d56Sopenharmony_ci   existing :class:`~pstats.Stats` object, the :meth:`~pstats.Stats.add` method
3477db96d56Sopenharmony_ci   can be used.
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_ci   Instead of reading the profile data from a file, a :class:`cProfile.Profile`
3507db96d56Sopenharmony_ci   or :class:`profile.Profile` object can be used as the profile data source.
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ci   :class:`Stats` objects have the following methods:
3537db96d56Sopenharmony_ci
3547db96d56Sopenharmony_ci   .. method:: strip_dirs()
3557db96d56Sopenharmony_ci
3567db96d56Sopenharmony_ci      This method for the :class:`Stats` class removes all leading path
3577db96d56Sopenharmony_ci      information from file names.  It is very useful in reducing the size of
3587db96d56Sopenharmony_ci      the printout to fit within (close to) 80 columns.  This method modifies
3597db96d56Sopenharmony_ci      the object, and the stripped information is lost.  After performing a
3607db96d56Sopenharmony_ci      strip operation, the object is considered to have its entries in a
3617db96d56Sopenharmony_ci      "random" order, as it was just after object initialization and loading.
3627db96d56Sopenharmony_ci      If :meth:`~pstats.Stats.strip_dirs` causes two function names to be
3637db96d56Sopenharmony_ci      indistinguishable (they are on the same line of the same filename, and
3647db96d56Sopenharmony_ci      have the same function name), then the statistics for these two entries
3657db96d56Sopenharmony_ci      are accumulated into a single entry.
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ci
3687db96d56Sopenharmony_ci   .. method:: add(*filenames)
3697db96d56Sopenharmony_ci
3707db96d56Sopenharmony_ci      This method of the :class:`Stats` class accumulates additional profiling
3717db96d56Sopenharmony_ci      information into the current profiling object.  Its arguments should refer
3727db96d56Sopenharmony_ci      to filenames created by the corresponding version of :func:`profile.run`
3737db96d56Sopenharmony_ci      or :func:`cProfile.run`. Statistics for identically named (re: file, line,
3747db96d56Sopenharmony_ci      name) functions are automatically accumulated into single function
3757db96d56Sopenharmony_ci      statistics.
3767db96d56Sopenharmony_ci
3777db96d56Sopenharmony_ci
3787db96d56Sopenharmony_ci   .. method:: dump_stats(filename)
3797db96d56Sopenharmony_ci
3807db96d56Sopenharmony_ci      Save the data loaded into the :class:`Stats` object to a file named
3817db96d56Sopenharmony_ci      *filename*.  The file is created if it does not exist, and is overwritten
3827db96d56Sopenharmony_ci      if it already exists.  This is equivalent to the method of the same name
3837db96d56Sopenharmony_ci      on the :class:`profile.Profile` and :class:`cProfile.Profile` classes.
3847db96d56Sopenharmony_ci
3857db96d56Sopenharmony_ci
3867db96d56Sopenharmony_ci   .. method:: sort_stats(*keys)
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci      This method modifies the :class:`Stats` object by sorting it according to
3897db96d56Sopenharmony_ci      the supplied criteria.  The argument can be either a string or a SortKey
3907db96d56Sopenharmony_ci      enum identifying the basis of a sort (example: ``'time'``, ``'name'``,
3917db96d56Sopenharmony_ci      ``SortKey.TIME`` or ``SortKey.NAME``). The SortKey enums argument have
3927db96d56Sopenharmony_ci      advantage over the string argument in that it is more robust and less
3937db96d56Sopenharmony_ci      error prone.
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_ci      When more than one key is provided, then additional keys are used as
3967db96d56Sopenharmony_ci      secondary criteria when there is equality in all keys selected before
3977db96d56Sopenharmony_ci      them.  For example, ``sort_stats(SortKey.NAME, SortKey.FILE)`` will sort
3987db96d56Sopenharmony_ci      all the entries according to their function name, and resolve all ties
3997db96d56Sopenharmony_ci      (identical function names) by sorting by file name.
4007db96d56Sopenharmony_ci
4017db96d56Sopenharmony_ci      For the string argument, abbreviations can be used for any key names, as
4027db96d56Sopenharmony_ci      long as the abbreviation is unambiguous.
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_ci      The following are the valid string and SortKey:
4057db96d56Sopenharmony_ci
4067db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4077db96d56Sopenharmony_ci      | Valid String Arg | Valid enum Arg      | Meaning              |
4087db96d56Sopenharmony_ci      +==================+=====================+======================+
4097db96d56Sopenharmony_ci      | ``'calls'``      | SortKey.CALLS       | call count           |
4107db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4117db96d56Sopenharmony_ci      | ``'cumulative'`` | SortKey.CUMULATIVE  | cumulative time      |
4127db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4137db96d56Sopenharmony_ci      | ``'cumtime'``    | N/A                 | cumulative time      |
4147db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4157db96d56Sopenharmony_ci      | ``'file'``       | N/A                 | file name            |
4167db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4177db96d56Sopenharmony_ci      | ``'filename'``   | SortKey.FILENAME    | file name            |
4187db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4197db96d56Sopenharmony_ci      | ``'module'``     | N/A                 | file name            |
4207db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4217db96d56Sopenharmony_ci      | ``'ncalls'``     | N/A                 | call count           |
4227db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4237db96d56Sopenharmony_ci      | ``'pcalls'``     | SortKey.PCALLS      | primitive call count |
4247db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4257db96d56Sopenharmony_ci      | ``'line'``       | SortKey.LINE        | line number          |
4267db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4277db96d56Sopenharmony_ci      | ``'name'``       | SortKey.NAME        | function name        |
4287db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4297db96d56Sopenharmony_ci      | ``'nfl'``        | SortKey.NFL         | name/file/line       |
4307db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4317db96d56Sopenharmony_ci      | ``'stdname'``    | SortKey.STDNAME     | standard name        |
4327db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4337db96d56Sopenharmony_ci      | ``'time'``       | SortKey.TIME        | internal time        |
4347db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4357db96d56Sopenharmony_ci      | ``'tottime'``    | N/A                 | internal time        |
4367db96d56Sopenharmony_ci      +------------------+---------------------+----------------------+
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_ci      Note that all sorts on statistics are in descending order (placing most
4397db96d56Sopenharmony_ci      time consuming items first), where as name, file, and line number searches
4407db96d56Sopenharmony_ci      are in ascending order (alphabetical). The subtle distinction between
4417db96d56Sopenharmony_ci      ``SortKey.NFL`` and ``SortKey.STDNAME`` is that the standard name is a
4427db96d56Sopenharmony_ci      sort of the name as printed, which means that the embedded line numbers
4437db96d56Sopenharmony_ci      get compared in an odd way.  For example, lines 3, 20, and 40 would (if
4447db96d56Sopenharmony_ci      the file names were the same) appear in the string order 20, 3 and 40.
4457db96d56Sopenharmony_ci      In contrast, ``SortKey.NFL`` does a numeric compare of the line numbers.
4467db96d56Sopenharmony_ci      In fact, ``sort_stats(SortKey.NFL)`` is the same as
4477db96d56Sopenharmony_ci      ``sort_stats(SortKey.NAME, SortKey.FILENAME, SortKey.LINE)``.
4487db96d56Sopenharmony_ci
4497db96d56Sopenharmony_ci      For backward-compatibility reasons, the numeric arguments ``-1``, ``0``,
4507db96d56Sopenharmony_ci      ``1``, and ``2`` are permitted.  They are interpreted as ``'stdname'``,
4517db96d56Sopenharmony_ci      ``'calls'``, ``'time'``, and ``'cumulative'`` respectively.  If this old
4527db96d56Sopenharmony_ci      style format (numeric) is used, only one sort key (the numeric key) will
4537db96d56Sopenharmony_ci      be used, and additional arguments will be silently ignored.
4547db96d56Sopenharmony_ci
4557db96d56Sopenharmony_ci      .. For compatibility with the old profiler.
4567db96d56Sopenharmony_ci
4577db96d56Sopenharmony_ci      .. versionadded:: 3.7
4587db96d56Sopenharmony_ci         Added the SortKey enum.
4597db96d56Sopenharmony_ci
4607db96d56Sopenharmony_ci   .. method:: reverse_order()
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ci      This method for the :class:`Stats` class reverses the ordering of the
4637db96d56Sopenharmony_ci      basic list within the object.  Note that by default ascending vs
4647db96d56Sopenharmony_ci      descending order is properly selected based on the sort key of choice.
4657db96d56Sopenharmony_ci
4667db96d56Sopenharmony_ci      .. This method is provided primarily for compatibility with the old
4677db96d56Sopenharmony_ci         profiler.
4687db96d56Sopenharmony_ci
4697db96d56Sopenharmony_ci
4707db96d56Sopenharmony_ci   .. method:: print_stats(*restrictions)
4717db96d56Sopenharmony_ci
4727db96d56Sopenharmony_ci      This method for the :class:`Stats` class prints out a report as described
4737db96d56Sopenharmony_ci      in the :func:`profile.run` definition.
4747db96d56Sopenharmony_ci
4757db96d56Sopenharmony_ci      The order of the printing is based on the last
4767db96d56Sopenharmony_ci      :meth:`~pstats.Stats.sort_stats` operation done on the object (subject to
4777db96d56Sopenharmony_ci      caveats in :meth:`~pstats.Stats.add` and
4787db96d56Sopenharmony_ci      :meth:`~pstats.Stats.strip_dirs`).
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci      The arguments provided (if any) can be used to limit the list down to the
4817db96d56Sopenharmony_ci      significant entries.  Initially, the list is taken to be the complete set
4827db96d56Sopenharmony_ci      of profiled functions.  Each restriction is either an integer (to select a
4837db96d56Sopenharmony_ci      count of lines), or a decimal fraction between 0.0 and 1.0 inclusive (to
4847db96d56Sopenharmony_ci      select a percentage of lines), or a string that will interpreted as a
4857db96d56Sopenharmony_ci      regular expression (to pattern match the standard name that is printed).
4867db96d56Sopenharmony_ci      If several restrictions are provided, then they are applied sequentially.
4877db96d56Sopenharmony_ci      For example::
4887db96d56Sopenharmony_ci
4897db96d56Sopenharmony_ci         print_stats(.1, 'foo:')
4907db96d56Sopenharmony_ci
4917db96d56Sopenharmony_ci      would first limit the printing to first 10% of list, and then only print
4927db96d56Sopenharmony_ci      functions that were part of filename :file:`.\*foo:`.  In contrast, the
4937db96d56Sopenharmony_ci      command::
4947db96d56Sopenharmony_ci
4957db96d56Sopenharmony_ci         print_stats('foo:', .1)
4967db96d56Sopenharmony_ci
4977db96d56Sopenharmony_ci      would limit the list to all functions having file names :file:`.\*foo:`,
4987db96d56Sopenharmony_ci      and then proceed to only print the first 10% of them.
4997db96d56Sopenharmony_ci
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ci   .. method:: print_callers(*restrictions)
5027db96d56Sopenharmony_ci
5037db96d56Sopenharmony_ci      This method for the :class:`Stats` class prints a list of all functions
5047db96d56Sopenharmony_ci      that called each function in the profiled database.  The ordering is
5057db96d56Sopenharmony_ci      identical to that provided by :meth:`~pstats.Stats.print_stats`, and the
5067db96d56Sopenharmony_ci      definition of the restricting argument is also identical.  Each caller is
5077db96d56Sopenharmony_ci      reported on its own line.  The format differs slightly depending on the
5087db96d56Sopenharmony_ci      profiler that produced the stats:
5097db96d56Sopenharmony_ci
5107db96d56Sopenharmony_ci      * With :mod:`profile`, a number is shown in parentheses after each caller
5117db96d56Sopenharmony_ci        to show how many times this specific call was made.  For convenience, a
5127db96d56Sopenharmony_ci        second non-parenthesized number repeats the cumulative time spent in the
5137db96d56Sopenharmony_ci        function at the right.
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci      * With :mod:`cProfile`, each caller is preceded by three numbers: the
5167db96d56Sopenharmony_ci        number of times this specific call was made, and the total and
5177db96d56Sopenharmony_ci        cumulative times spent in the current function while it was invoked by
5187db96d56Sopenharmony_ci        this specific caller.
5197db96d56Sopenharmony_ci
5207db96d56Sopenharmony_ci
5217db96d56Sopenharmony_ci   .. method:: print_callees(*restrictions)
5227db96d56Sopenharmony_ci
5237db96d56Sopenharmony_ci      This method for the :class:`Stats` class prints a list of all function
5247db96d56Sopenharmony_ci      that were called by the indicated function.  Aside from this reversal of
5257db96d56Sopenharmony_ci      direction of calls (re: called vs was called by), the arguments and
5267db96d56Sopenharmony_ci      ordering are identical to the :meth:`~pstats.Stats.print_callers` method.
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_ci
5297db96d56Sopenharmony_ci   .. method:: get_stats_profile()
5307db96d56Sopenharmony_ci
5317db96d56Sopenharmony_ci      This method returns an instance of StatsProfile, which contains a mapping
5327db96d56Sopenharmony_ci      of function names to instances of FunctionProfile. Each FunctionProfile
5337db96d56Sopenharmony_ci      instance holds information related to the function's profile such as how
5347db96d56Sopenharmony_ci      long the function took to run, how many times it was called, etc...
5357db96d56Sopenharmony_ci
5367db96d56Sopenharmony_ci      .. versionadded:: 3.9
5377db96d56Sopenharmony_ci         Added the following dataclasses: StatsProfile, FunctionProfile.
5387db96d56Sopenharmony_ci         Added the following function: get_stats_profile.
5397db96d56Sopenharmony_ci
5407db96d56Sopenharmony_ci.. _deterministic-profiling:
5417db96d56Sopenharmony_ci
5427db96d56Sopenharmony_ciWhat Is Deterministic Profiling?
5437db96d56Sopenharmony_ci================================
5447db96d56Sopenharmony_ci
5457db96d56Sopenharmony_ci:dfn:`Deterministic profiling` is meant to reflect the fact that all *function
5467db96d56Sopenharmony_cicall*, *function return*, and *exception* events are monitored, and precise
5477db96d56Sopenharmony_citimings are made for the intervals between these events (during which time the
5487db96d56Sopenharmony_ciuser's code is executing).  In contrast, :dfn:`statistical profiling` (which is
5497db96d56Sopenharmony_cinot done by this module) randomly samples the effective instruction pointer, and
5507db96d56Sopenharmony_cideduces where time is being spent.  The latter technique traditionally involves
5517db96d56Sopenharmony_ciless overhead (as the code does not need to be instrumented), but provides only
5527db96d56Sopenharmony_cirelative indications of where time is being spent.
5537db96d56Sopenharmony_ci
5547db96d56Sopenharmony_ciIn Python, since there is an interpreter active during execution, the presence
5557db96d56Sopenharmony_ciof instrumented code is not required in order to do deterministic profiling.
5567db96d56Sopenharmony_ciPython automatically provides a :dfn:`hook` (optional callback) for each event.
5577db96d56Sopenharmony_ciIn addition, the interpreted nature of Python tends to add so much overhead to
5587db96d56Sopenharmony_ciexecution, that deterministic profiling tends to only add small processing
5597db96d56Sopenharmony_cioverhead in typical applications.  The result is that deterministic profiling is
5607db96d56Sopenharmony_cinot that expensive, yet provides extensive run time statistics about the
5617db96d56Sopenharmony_ciexecution of a Python program.
5627db96d56Sopenharmony_ci
5637db96d56Sopenharmony_ciCall count statistics can be used to identify bugs in code (surprising counts),
5647db96d56Sopenharmony_ciand to identify possible inline-expansion points (high call counts).  Internal
5657db96d56Sopenharmony_citime statistics can be used to identify "hot loops" that should be carefully
5667db96d56Sopenharmony_cioptimized.  Cumulative time statistics should be used to identify high level
5677db96d56Sopenharmony_cierrors in the selection of algorithms.  Note that the unusual handling of
5687db96d56Sopenharmony_cicumulative times in this profiler allows statistics for recursive
5697db96d56Sopenharmony_ciimplementations of algorithms to be directly compared to iterative
5707db96d56Sopenharmony_ciimplementations.
5717db96d56Sopenharmony_ci
5727db96d56Sopenharmony_ci
5737db96d56Sopenharmony_ci.. _profile-limitations:
5747db96d56Sopenharmony_ci
5757db96d56Sopenharmony_ciLimitations
5767db96d56Sopenharmony_ci===========
5777db96d56Sopenharmony_ci
5787db96d56Sopenharmony_ciOne limitation has to do with accuracy of timing information. There is a
5797db96d56Sopenharmony_cifundamental problem with deterministic profilers involving accuracy.  The most
5807db96d56Sopenharmony_ciobvious restriction is that the underlying "clock" is only ticking at a rate
5817db96d56Sopenharmony_ci(typically) of about .001 seconds.  Hence no measurements will be more accurate
5827db96d56Sopenharmony_cithan the underlying clock.  If enough measurements are taken, then the "error"
5837db96d56Sopenharmony_ciwill tend to average out. Unfortunately, removing this first error induces a
5847db96d56Sopenharmony_cisecond source of error.
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_ciThe second problem is that it "takes a while" from when an event is dispatched
5877db96d56Sopenharmony_ciuntil the profiler's call to get the time actually *gets* the state of the
5887db96d56Sopenharmony_ciclock.  Similarly, there is a certain lag when exiting the profiler event
5897db96d56Sopenharmony_cihandler from the time that the clock's value was obtained (and then squirreled
5907db96d56Sopenharmony_ciaway), until the user's code is once again executing.  As a result, functions
5917db96d56Sopenharmony_cithat are called many times, or call many functions, will typically accumulate
5927db96d56Sopenharmony_cithis error. The error that accumulates in this fashion is typically less than
5937db96d56Sopenharmony_cithe accuracy of the clock (less than one clock tick), but it *can* accumulate
5947db96d56Sopenharmony_ciand become very significant.
5957db96d56Sopenharmony_ci
5967db96d56Sopenharmony_ciThe problem is more important with :mod:`profile` than with the lower-overhead
5977db96d56Sopenharmony_ci:mod:`cProfile`.  For this reason, :mod:`profile` provides a means of
5987db96d56Sopenharmony_cicalibrating itself for a given platform so that this error can be
5997db96d56Sopenharmony_ciprobabilistically (on the average) removed. After the profiler is calibrated, it
6007db96d56Sopenharmony_ciwill be more accurate (in a least square sense), but it will sometimes produce
6017db96d56Sopenharmony_cinegative numbers (when call counts are exceptionally low, and the gods of
6027db96d56Sopenharmony_ciprobability work against you :-). )  Do *not* be alarmed by negative numbers in
6037db96d56Sopenharmony_cithe profile.  They should *only* appear if you have calibrated your profiler,
6047db96d56Sopenharmony_ciand the results are actually better than without calibration.
6057db96d56Sopenharmony_ci
6067db96d56Sopenharmony_ci
6077db96d56Sopenharmony_ci.. _profile-calibration:
6087db96d56Sopenharmony_ci
6097db96d56Sopenharmony_ciCalibration
6107db96d56Sopenharmony_ci===========
6117db96d56Sopenharmony_ci
6127db96d56Sopenharmony_ciThe profiler of the :mod:`profile` module subtracts a constant from each event
6137db96d56Sopenharmony_cihandling time to compensate for the overhead of calling the time function, and
6147db96d56Sopenharmony_cisocking away the results.  By default, the constant is 0. The following
6157db96d56Sopenharmony_ciprocedure can be used to obtain a better constant for a given platform (see
6167db96d56Sopenharmony_ci:ref:`profile-limitations`). ::
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci   import profile
6197db96d56Sopenharmony_ci   pr = profile.Profile()
6207db96d56Sopenharmony_ci   for i in range(5):
6217db96d56Sopenharmony_ci       print(pr.calibrate(10000))
6227db96d56Sopenharmony_ci
6237db96d56Sopenharmony_ciThe method executes the number of Python calls given by the argument, directly
6247db96d56Sopenharmony_ciand again under the profiler, measuring the time for both. It then computes the
6257db96d56Sopenharmony_cihidden overhead per profiler event, and returns that as a float.  For example,
6267db96d56Sopenharmony_cion a 1.8Ghz Intel Core i5 running macOS, and using Python's time.process_time() as
6277db96d56Sopenharmony_cithe timer, the magical number is about 4.04e-6.
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ciThe object of this exercise is to get a fairly consistent result. If your
6307db96d56Sopenharmony_cicomputer is *very* fast, or your timer function has poor resolution, you might
6317db96d56Sopenharmony_cihave to pass 100000, or even 1000000, to get consistent results.
6327db96d56Sopenharmony_ci
6337db96d56Sopenharmony_ciWhen you have a consistent answer, there are three ways you can use it::
6347db96d56Sopenharmony_ci
6357db96d56Sopenharmony_ci   import profile
6367db96d56Sopenharmony_ci
6377db96d56Sopenharmony_ci   # 1. Apply computed bias to all Profile instances created hereafter.
6387db96d56Sopenharmony_ci   profile.Profile.bias = your_computed_bias
6397db96d56Sopenharmony_ci
6407db96d56Sopenharmony_ci   # 2. Apply computed bias to a specific Profile instance.
6417db96d56Sopenharmony_ci   pr = profile.Profile()
6427db96d56Sopenharmony_ci   pr.bias = your_computed_bias
6437db96d56Sopenharmony_ci
6447db96d56Sopenharmony_ci   # 3. Specify computed bias in instance constructor.
6457db96d56Sopenharmony_ci   pr = profile.Profile(bias=your_computed_bias)
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_ciIf you have a choice, you are better off choosing a smaller constant, and then
6487db96d56Sopenharmony_ciyour results will "less often" show up as negative in profile statistics.
6497db96d56Sopenharmony_ci
6507db96d56Sopenharmony_ci.. _profile-timers:
6517db96d56Sopenharmony_ci
6527db96d56Sopenharmony_ciUsing a custom timer
6537db96d56Sopenharmony_ci====================
6547db96d56Sopenharmony_ci
6557db96d56Sopenharmony_ciIf you want to change how current time is determined (for example, to force use
6567db96d56Sopenharmony_ciof wall-clock time or elapsed process time), pass the timing function you want
6577db96d56Sopenharmony_cito the :class:`Profile` class constructor::
6587db96d56Sopenharmony_ci
6597db96d56Sopenharmony_ci    pr = profile.Profile(your_time_func)
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_ciThe resulting profiler will then call ``your_time_func``. Depending on whether
6627db96d56Sopenharmony_ciyou are using :class:`profile.Profile` or :class:`cProfile.Profile`,
6637db96d56Sopenharmony_ci``your_time_func``'s return value will be interpreted differently:
6647db96d56Sopenharmony_ci
6657db96d56Sopenharmony_ci:class:`profile.Profile`
6667db96d56Sopenharmony_ci   ``your_time_func`` should return a single number, or a list of numbers whose
6677db96d56Sopenharmony_ci   sum is the current time (like what :func:`os.times` returns).  If the
6687db96d56Sopenharmony_ci   function returns a single time number, or the list of returned numbers has
6697db96d56Sopenharmony_ci   length 2, then you will get an especially fast version of the dispatch
6707db96d56Sopenharmony_ci   routine.
6717db96d56Sopenharmony_ci
6727db96d56Sopenharmony_ci   Be warned that you should calibrate the profiler class for the timer function
6737db96d56Sopenharmony_ci   that you choose (see :ref:`profile-calibration`).  For most machines, a timer
6747db96d56Sopenharmony_ci   that returns a lone integer value will provide the best results in terms of
6757db96d56Sopenharmony_ci   low overhead during profiling.  (:func:`os.times` is *pretty* bad, as it
6767db96d56Sopenharmony_ci   returns a tuple of floating point values).  If you want to substitute a
6777db96d56Sopenharmony_ci   better timer in the cleanest fashion, derive a class and hardwire a
6787db96d56Sopenharmony_ci   replacement dispatch method that best handles your timer call, along with the
6797db96d56Sopenharmony_ci   appropriate calibration constant.
6807db96d56Sopenharmony_ci
6817db96d56Sopenharmony_ci:class:`cProfile.Profile`
6827db96d56Sopenharmony_ci   ``your_time_func`` should return a single number.  If it returns integers,
6837db96d56Sopenharmony_ci   you can also invoke the class constructor with a second argument specifying
6847db96d56Sopenharmony_ci   the real duration of one unit of time.  For example, if
6857db96d56Sopenharmony_ci   ``your_integer_time_func`` returns times measured in thousands of seconds,
6867db96d56Sopenharmony_ci   you would construct the :class:`Profile` instance as follows::
6877db96d56Sopenharmony_ci
6887db96d56Sopenharmony_ci      pr = cProfile.Profile(your_integer_time_func, 0.001)
6897db96d56Sopenharmony_ci
6907db96d56Sopenharmony_ci   As the :class:`cProfile.Profile` class cannot be calibrated, custom timer
6917db96d56Sopenharmony_ci   functions should be used with care and should be as fast as possible.  For
6927db96d56Sopenharmony_ci   the best results with a custom timer, it might be necessary to hard-code it
6937db96d56Sopenharmony_ci   in the C source of the internal :mod:`_lsprof` module.
6947db96d56Sopenharmony_ci
6957db96d56Sopenharmony_ciPython 3.3 adds several new functions in :mod:`time` that can be used to make
6967db96d56Sopenharmony_ciprecise measurements of process or wall-clock time. For example, see
6977db96d56Sopenharmony_ci:func:`time.perf_counter`.
698