1050 lines
89 KiB
HTML
1050 lines
89 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html lang="en" data-content_root="../">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<meta property="og:title" content="The Python Profilers" />
|
||
<meta property="og:type" content="website" />
|
||
<meta property="og:url" content="https://docs.python.org/3/library/profile.html" />
|
||
<meta property="og:site_name" content="Python documentation" />
|
||
<meta property="og:description" content="Source code: Lib/profile.py and Lib/pstats.py Introduction to the profilers: cProfile and profile provide deterministic profiling of Python programs. A profile is a set of statistics that describes..." />
|
||
<meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
|
||
<meta property="og:image:alt" content="Python documentation" />
|
||
<meta name="description" content="Source code: Lib/profile.py and Lib/pstats.py Introduction to the profilers: cProfile and profile provide deterministic profiling of Python programs. A profile is a set of statistics that describes..." />
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
<meta name="theme-color" content="#3776ab">
|
||
|
||
<title>The Python Profilers — Python 3.13.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=23252803" />
|
||
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
|
||
|
||
<script src="../_static/documentation_options.js?v=5d57ca2d"></script>
|
||
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
||
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||
|
||
<script src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="Search within Python 3.13.3 documentation"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="About these documents" href="../about.html" />
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||
<link rel="next" title="timeit — Measure execution time of small code snippets" href="timeit.html" />
|
||
<link rel="prev" title="pdb — The Python Debugger" href="pdb.html" />
|
||
|
||
<link rel="canonical" href="https://docs.python.org/3/library/profile.html">
|
||
|
||
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/menu.js"></script>
|
||
<script type="text/javascript" src="../_static/search-focus.js"></script>
|
||
<script type="text/javascript" src="../_static/themetoggle.js"></script>
|
||
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
|
||
<meta name="readthedocs-addons-api-version" content="1">
|
||
|
||
</head>
|
||
<body>
|
||
<div class="mobile-nav">
|
||
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
|
||
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
|
||
<nav class="nav-content" role="navigation">
|
||
<label for="menuToggler" class="toggler__label">
|
||
<span></span>
|
||
</label>
|
||
<span class="nav-items-wrapper">
|
||
<a href="https://www.python.org/" class="nav-logo">
|
||
<img src="../_static/py.svg" alt="Python logo"/>
|
||
</a>
|
||
<span class="version_switcher_placeholder"></span>
|
||
<form role="search" class="search" action="../search.html" method="get">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
|
||
<path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
|
||
</svg>
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
|
||
<input type="submit" value="Go"/>
|
||
</form>
|
||
</span>
|
||
</nav>
|
||
<div class="menu-wrapper">
|
||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||
<div class="language_switcher_placeholder"></div>
|
||
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label>
|
||
<div>
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">The Python Profilers</a><ul>
|
||
<li><a class="reference internal" href="#introduction-to-the-profilers">Introduction to the profilers</a></li>
|
||
<li><a class="reference internal" href="#instant-user-s-manual">Instant User’s Manual</a></li>
|
||
<li><a class="reference internal" href="#module-cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code> and <code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code> Module Reference</a></li>
|
||
<li><a class="reference internal" href="#the-stats-class">The <code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code> Class</a></li>
|
||
<li><a class="reference internal" href="#what-is-deterministic-profiling">What Is Deterministic Profiling?</a></li>
|
||
<li><a class="reference internal" href="#limitations">Limitations</a></li>
|
||
<li><a class="reference internal" href="#calibration">Calibration</a></li>
|
||
<li><a class="reference internal" href="#using-a-custom-timer">Using a custom timer</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
<div>
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="pdb.html"
|
||
title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">pdb</span></code> — The Python Debugger</a></p>
|
||
</div>
|
||
<div>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="timeit.html"
|
||
title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">timeit</span></code> — Measure execution time of small code snippets</a></p>
|
||
</div>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/main/Doc/library/profile.rst"
|
||
rel="nofollow">Show Source
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div class="related" role="navigation" aria-label="Related">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="timeit.html" title="timeit — Measure execution time of small code snippets"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="pdb.html" title="pdb — The Python Debugger"
|
||
accesskey="P">previous</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.13.3 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="debug.html" accesskey="U">Debugging and Profiling</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">The Python Profilers</a></li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
<li class="right">
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label> |</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section id="the-python-profilers">
|
||
<span id="profile"></span><h1>The Python Profilers<a class="headerlink" href="#the-python-profilers" title="Link to this heading">¶</a></h1>
|
||
<p><strong>Source code:</strong> <a class="extlink-source reference external" href="https://github.com/python/cpython/tree/3.13/Lib/profile.py">Lib/profile.py</a> and <a class="extlink-source reference external" href="https://github.com/python/cpython/tree/3.13/Lib/pstats.py">Lib/pstats.py</a></p>
|
||
<hr class="docutils" />
|
||
<section id="introduction-to-the-profilers">
|
||
<span id="profiler-introduction"></span><h2>Introduction to the profilers<a class="headerlink" href="#introduction-to-the-profilers" title="Link to this heading">¶</a></h2>
|
||
<p id="index-0"><a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a> and <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> provide <em class="dfn">deterministic profiling</em> of
|
||
Python programs. A <em class="dfn">profile</em> is a set of statistics that describes how
|
||
often and for how long various parts of the program executed. These statistics
|
||
can be formatted into reports via the <a class="reference internal" href="#module-pstats" title="pstats: Statistics object for use with the profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">pstats</span></code></a> module.</p>
|
||
<p>The Python standard library provides two different implementations of the same
|
||
profiling interface:</p>
|
||
<ol class="arabic simple">
|
||
<li><p><a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a> is recommended for most users; it’s a C extension with
|
||
reasonable overhead that makes it suitable for profiling long-running
|
||
programs. Based on <code class="xref py py-mod docutils literal notranslate"><span class="pre">lsprof</span></code>, contributed by Brett Rosen and Ted
|
||
Czotter.</p></li>
|
||
<li><p><a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a>, a pure Python module whose interface is imitated by
|
||
<a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a>, but which adds significant overhead to profiled programs.
|
||
If you’re trying to extend the profiler in some way, the task might be easier
|
||
with this module. Originally designed and written by Jim Roskind.</p></li>
|
||
</ol>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>The profiler modules are designed to provide an execution profile for a given
|
||
program, not for benchmarking purposes (for that, there is <a class="reference internal" href="timeit.html#module-timeit" title="timeit: Measure the execution time of small code snippets."><code class="xref py py-mod docutils literal notranslate"><span class="pre">timeit</span></code></a> for
|
||
reasonably accurate results). This particularly applies to benchmarking
|
||
Python code against C code: the profilers introduce overhead for Python code,
|
||
but not for C-level functions, and so the C code would seem faster than any
|
||
Python one.</p>
|
||
</div>
|
||
</section>
|
||
<section id="instant-user-s-manual">
|
||
<span id="profile-instant"></span><h2>Instant User’s Manual<a class="headerlink" href="#instant-user-s-manual" title="Link to this heading">¶</a></h2>
|
||
<p>This section is provided for users that “don’t want to read the manual.” It
|
||
provides a very brief overview, and allows a user to rapidly perform profiling
|
||
on an existing application.</p>
|
||
<p>To profile a function that takes a single argument, you can do:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">cProfile</span>
|
||
<span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
|
||
<span class="n">cProfile</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s1">'re.compile("foo|bar")'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>(Use <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> instead of <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a> if the latter is not available on
|
||
your system.)</p>
|
||
<p>The above action would run <a class="reference internal" href="re.html#re.compile" title="re.compile"><code class="xref py py-func docutils literal notranslate"><span class="pre">re.compile()</span></code></a> and print profile results like
|
||
the following:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span> <span class="mi">214</span> <span class="n">function</span> <span class="n">calls</span> <span class="p">(</span><span class="mi">207</span> <span class="n">primitive</span> <span class="n">calls</span><span class="p">)</span> <span class="ow">in</span> <span class="mf">0.002</span> <span class="n">seconds</span>
|
||
|
||
<span class="n">Ordered</span> <span class="n">by</span><span class="p">:</span> <span class="n">cumulative</span> <span class="n">time</span>
|
||
|
||
<span class="n">ncalls</span> <span class="n">tottime</span> <span class="n">percall</span> <span class="n">cumtime</span> <span class="n">percall</span> <span class="n">filename</span><span class="p">:</span><span class="n">lineno</span><span class="p">(</span><span class="n">function</span><span class="p">)</span>
|
||
<span class="mi">1</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.002</span> <span class="mf">0.002</span> <span class="p">{</span><span class="n">built</span><span class="o">-</span><span class="ow">in</span> <span class="n">method</span> <span class="n">builtins</span><span class="o">.</span><span class="n">exec</span><span class="p">}</span>
|
||
<span class="mi">1</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.001</span> <span class="mf">0.001</span> <span class="o"><</span><span class="n">string</span><span class="o">></span><span class="p">:</span><span class="mi">1</span><span class="p">(</span><span class="o"><</span><span class="n">module</span><span class="o">></span><span class="p">)</span>
|
||
<span class="mi">1</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.001</span> <span class="mf">0.001</span> <span class="fm">__init__</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">250</span><span class="p">(</span><span class="nb">compile</span><span class="p">)</span>
|
||
<span class="mi">1</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.001</span> <span class="mf">0.001</span> <span class="fm">__init__</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">289</span><span class="p">(</span><span class="n">_compile</span><span class="p">)</span>
|
||
<span class="mi">1</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="n">_compiler</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">759</span><span class="p">(</span><span class="nb">compile</span><span class="p">)</span>
|
||
<span class="mi">1</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="n">_parser</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">937</span><span class="p">(</span><span class="n">parse</span><span class="p">)</span>
|
||
<span class="mi">1</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="n">_compiler</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">598</span><span class="p">(</span><span class="n">_code</span><span class="p">)</span>
|
||
<span class="mi">1</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="mf">0.000</span> <span class="n">_parser</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">435</span><span class="p">(</span><span class="n">_parse_sub</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The first line indicates that 214 calls were monitored. Of those calls, 207
|
||
were <em class="dfn">primitive</em>, meaning that the call was not induced via recursion. The
|
||
next line: <code class="docutils literal notranslate"><span class="pre">Ordered</span> <span class="pre">by:</span> <span class="pre">cumulative</span> <span class="pre">time</span></code> indicates the output is sorted
|
||
by the <code class="docutils literal notranslate"><span class="pre">cumtime</span></code> values. The column headings include:</p>
|
||
<dl class="simple">
|
||
<dt>ncalls</dt><dd><p>for the number of calls.</p>
|
||
</dd>
|
||
<dt>tottime</dt><dd><p>for the total time spent in the given function (and excluding time made in
|
||
calls to sub-functions)</p>
|
||
</dd>
|
||
<dt>percall</dt><dd><p>is the quotient of <code class="docutils literal notranslate"><span class="pre">tottime</span></code> divided by <code class="docutils literal notranslate"><span class="pre">ncalls</span></code></p>
|
||
</dd>
|
||
<dt>cumtime</dt><dd><p>is the cumulative time spent in this and all subfunctions (from invocation
|
||
till exit). This figure is accurate <em>even</em> for recursive functions.</p>
|
||
</dd>
|
||
<dt>percall</dt><dd><p>is the quotient of <code class="docutils literal notranslate"><span class="pre">cumtime</span></code> divided by primitive calls</p>
|
||
</dd>
|
||
<dt>filename:lineno(function)</dt><dd><p>provides the respective data of each function</p>
|
||
</dd>
|
||
</dl>
|
||
<p>When there are two numbers in the first column (for example <code class="docutils literal notranslate"><span class="pre">3/1</span></code>), it means
|
||
that the function recursed. The second value is the number of primitive calls
|
||
and the former is the total number of calls. Note that when the function does
|
||
not recurse, these two values are the same, and only the single figure is
|
||
printed.</p>
|
||
<p>Instead of printing the output at the end of the profile run, you can save the
|
||
results to a file by specifying a filename to the <code class="xref py py-func docutils literal notranslate"><span class="pre">run()</span></code> function:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">cProfile</span>
|
||
<span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
|
||
<span class="n">cProfile</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s1">'re.compile("foo|bar")'</span><span class="p">,</span> <span class="s1">'restats'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">pstats.Stats</span></code></a> class reads profile results from a file and formats
|
||
them in various ways.</p>
|
||
<p id="profile-cli">The files <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a> and <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> can also be invoked as a script to
|
||
profile another script. For example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">cProfile</span> <span class="p">[</span><span class="o">-</span><span class="n">o</span> <span class="n">output_file</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">s</span> <span class="n">sort_order</span><span class="p">]</span> <span class="p">(</span><span class="o">-</span><span class="n">m</span> <span class="n">module</span> <span class="o">|</span> <span class="n">myscript</span><span class="o">.</span><span class="n">py</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<dl class="std option">
|
||
<dt class="sig sig-object std" id="cmdoption-cProfile-o">
|
||
<span class="sig-name descname"><span class="pre">-o</span></span><span class="sig-prename descclassname"> <span class="pre"><output_file></span></span><a class="headerlink" href="#cmdoption-cProfile-o" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Writes the profile results to a file instead of to stdout.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="std option">
|
||
<dt class="sig sig-object std" id="cmdoption-cProfile-s">
|
||
<span class="sig-name descname"><span class="pre">-s</span></span><span class="sig-prename descclassname"> <span class="pre"><sort_order></span></span><a class="headerlink" href="#cmdoption-cProfile-s" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Specifies one of the <a class="reference internal" href="#pstats.Stats.sort_stats" title="pstats.Stats.sort_stats"><code class="xref py py-func docutils literal notranslate"><span class="pre">sort_stats()</span></code></a> sort values
|
||
to sort the output by.
|
||
This only applies when <a class="reference internal" href="#cmdoption-cProfile-o"><code class="xref std std-option docutils literal notranslate"><span class="pre">-o</span></code></a> is not supplied.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="std option">
|
||
<dt class="sig sig-object std" id="cmdoption-cProfile-m">
|
||
<span class="sig-name descname"><span class="pre">-m</span></span><span class="sig-prename descclassname"> <span class="pre"><module></span></span><a class="headerlink" href="#cmdoption-cProfile-m" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Specifies that a module is being profiled instead of a script.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.7: </span>Added the <code class="docutils literal notranslate"><span class="pre">-m</span></code> option to <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a>.</p>
|
||
</div>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.8: </span>Added the <code class="docutils literal notranslate"><span class="pre">-m</span></code> option to <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a>.</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<p>The <a class="reference internal" href="#module-pstats" title="pstats: Statistics object for use with the profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">pstats</span></code></a> module’s <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> class has a variety of methods
|
||
for manipulating and printing the data saved into a profile results file:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">pstats</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">pstats</span><span class="w"> </span><span class="kn">import</span> <span class="n">SortKey</span>
|
||
<span class="n">p</span> <span class="o">=</span> <span class="n">pstats</span><span class="o">.</span><span class="n">Stats</span><span class="p">(</span><span class="s1">'restats'</span><span class="p">)</span>
|
||
<span class="n">p</span><span class="o">.</span><span class="n">strip_dirs</span><span class="p">()</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">print_stats</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The <a class="reference internal" href="#pstats.Stats.strip_dirs" title="pstats.Stats.strip_dirs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">strip_dirs()</span></code></a> method removed the extraneous path from all
|
||
the module names. The <a class="reference internal" href="#pstats.Stats.sort_stats" title="pstats.Stats.sort_stats"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sort_stats()</span></code></a> method sorted all the
|
||
entries according to the standard module/line/name string that is printed. The
|
||
<a class="reference internal" href="#pstats.Stats.print_stats" title="pstats.Stats.print_stats"><code class="xref py py-meth docutils literal notranslate"><span class="pre">print_stats()</span></code></a> method printed out all the statistics. You
|
||
might try the following sort calls:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">p</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="n">SortKey</span><span class="o">.</span><span class="n">NAME</span><span class="p">)</span>
|
||
<span class="n">p</span><span class="o">.</span><span class="n">print_stats</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The first call will actually sort the list by function name, and the second call
|
||
will print out the statistics. The following are some interesting calls to
|
||
experiment with:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">p</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="n">SortKey</span><span class="o">.</span><span class="n">CUMULATIVE</span><span class="p">)</span><span class="o">.</span><span class="n">print_stats</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This sorts the profile by cumulative time in a function, and then only prints
|
||
the ten most significant lines. If you want to understand what algorithms are
|
||
taking time, the above line is what you would use.</p>
|
||
<p>If you were looking to see what functions were looping a lot, and taking a lot
|
||
of time, you would do:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">p</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="n">SortKey</span><span class="o">.</span><span class="n">TIME</span><span class="p">)</span><span class="o">.</span><span class="n">print_stats</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>to sort according to time spent within each function, and then print the
|
||
statistics for the top ten functions.</p>
|
||
<p>You might also try:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">p</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="n">SortKey</span><span class="o">.</span><span class="n">FILENAME</span><span class="p">)</span><span class="o">.</span><span class="n">print_stats</span><span class="p">(</span><span class="s1">'__init__'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This will sort all the statistics by file name, and then print out statistics
|
||
for only the class init methods (since they are spelled with <code class="docutils literal notranslate"><span class="pre">__init__</span></code> in
|
||
them). As one final example, you could try:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">p</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="n">SortKey</span><span class="o">.</span><span class="n">TIME</span><span class="p">,</span> <span class="n">SortKey</span><span class="o">.</span><span class="n">CUMULATIVE</span><span class="p">)</span><span class="o">.</span><span class="n">print_stats</span><span class="p">(</span><span class="mf">.5</span><span class="p">,</span> <span class="s1">'init'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This line sorts statistics with a primary key of time, and a secondary key of
|
||
cumulative time, and then prints out some of the statistics. To be specific, the
|
||
list is first culled down to 50% (re: <code class="docutils literal notranslate"><span class="pre">.5</span></code>) of its original size, then only
|
||
lines containing <code class="docutils literal notranslate"><span class="pre">init</span></code> are maintained, and that sub-sub-list is printed.</p>
|
||
<p>If you wondered what functions called the above functions, you could now (<code class="docutils literal notranslate"><span class="pre">p</span></code>
|
||
is still sorted according to the last criteria) do:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">p</span><span class="o">.</span><span class="n">print_callers</span><span class="p">(</span><span class="mf">.5</span><span class="p">,</span> <span class="s1">'init'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>and you would get a list of callers for each of the listed functions.</p>
|
||
<p>If you want more functionality, you’re going to have to read the manual, or
|
||
guess what the following functions do:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">p</span><span class="o">.</span><span class="n">print_callees</span><span class="p">()</span>
|
||
<span class="n">p</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">'restats'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Invoked as a script, the <a class="reference internal" href="#module-pstats" title="pstats: Statistics object for use with the profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">pstats</span></code></a> module is a statistics browser for
|
||
reading and examining profile dumps. It has a simple line-oriented interface
|
||
(implemented using <a class="reference internal" href="cmd.html#module-cmd" title="cmd: Build line-oriented command interpreters."><code class="xref py py-mod docutils literal notranslate"><span class="pre">cmd</span></code></a>) and interactive help.</p>
|
||
</section>
|
||
<section id="module-cProfile">
|
||
<span id="profile-and-cprofile-module-reference"></span><h2><a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> and <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a> Module Reference<a class="headerlink" href="#module-cProfile" title="Link to this heading">¶</a></h2>
|
||
<p id="module-profile">Both the <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> and <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a> modules provide the following
|
||
functions:</p>
|
||
<dl class="py function">
|
||
<dt class="sig sig-object py" id="profile.run">
|
||
<span class="sig-prename descclassname"><span class="pre">profile.</span></span><span class="sig-name descname"><span class="pre">run</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">command</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">filename</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sort</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">-1</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#profile.run" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This function takes a single argument that can be passed to the <a class="reference internal" href="functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a>
|
||
function, and an optional file name. In all cases this routine executes:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">exec</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">__main__</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">,</span> <span class="n">__main__</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>and gathers profiling statistics from the execution. If no file name is
|
||
present, then this function automatically creates a <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a>
|
||
instance and prints a simple profiling report. If the sort value is specified,
|
||
it is passed to this <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> instance to control how the
|
||
results are sorted.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py function">
|
||
<dt class="sig sig-object py" id="profile.runctx">
|
||
<span class="sig-prename descclassname"><span class="pre">profile.</span></span><span class="sig-name descname"><span class="pre">runctx</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">command</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">globals</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">locals</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">filename</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sort</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">-1</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#profile.runctx" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This function is similar to <a class="reference internal" href="#profile.run" title="profile.run"><code class="xref py py-func docutils literal notranslate"><span class="pre">run()</span></code></a>, with added arguments to supply the
|
||
globals and locals mappings for the <em>command</em> string. This routine
|
||
executes:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">exec</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="nb">globals</span><span class="p">,</span> <span class="nb">locals</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>and gathers profiling statistics as in the <a class="reference internal" href="#profile.run" title="profile.run"><code class="xref py py-func docutils literal notranslate"><span class="pre">run()</span></code></a> function above.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py class">
|
||
<dt class="sig sig-object py" id="profile.Profile">
|
||
<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">profile.</span></span><span class="sig-name descname"><span class="pre">Profile</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">timer</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeunit</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0.0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">subcalls</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">builtins</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This class is normally only used if more precise control over profiling is
|
||
needed than what the <code class="xref py py-func docutils literal notranslate"><span class="pre">cProfile.run()</span></code> function provides.</p>
|
||
<p>A custom timer can be supplied for measuring how long code takes to run via
|
||
the <em>timer</em> argument. This must be a function that returns a single number
|
||
representing the current time. If the number is an integer, the <em>timeunit</em>
|
||
specifies a multiplier that specifies the duration of each unit of time. For
|
||
example, if the timer returns times measured in thousands of seconds, the
|
||
time unit would be <code class="docutils literal notranslate"><span class="pre">.001</span></code>.</p>
|
||
<p>Directly using the <a class="reference internal" href="#profile.Profile" title="profile.Profile"><code class="xref py py-class docutils literal notranslate"><span class="pre">Profile</span></code></a> class allows formatting profile results
|
||
without writing the profile data to a file:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">cProfile</span><span class="o">,</span><span class="w"> </span><span class="nn">pstats</span><span class="o">,</span><span class="w"> </span><span class="nn">io</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">pstats</span><span class="w"> </span><span class="kn">import</span> <span class="n">SortKey</span>
|
||
<span class="n">pr</span> <span class="o">=</span> <span class="n">cProfile</span><span class="o">.</span><span class="n">Profile</span><span class="p">()</span>
|
||
<span class="n">pr</span><span class="o">.</span><span class="n">enable</span><span class="p">()</span>
|
||
<span class="c1"># ... do something ...</span>
|
||
<span class="n">pr</span><span class="o">.</span><span class="n">disable</span><span class="p">()</span>
|
||
<span class="n">s</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
|
||
<span class="n">sortby</span> <span class="o">=</span> <span class="n">SortKey</span><span class="o">.</span><span class="n">CUMULATIVE</span>
|
||
<span class="n">ps</span> <span class="o">=</span> <span class="n">pstats</span><span class="o">.</span><span class="n">Stats</span><span class="p">(</span><span class="n">pr</span><span class="p">,</span> <span class="n">stream</span><span class="o">=</span><span class="n">s</span><span class="p">)</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="n">sortby</span><span class="p">)</span>
|
||
<span class="n">ps</span><span class="o">.</span><span class="n">print_stats</span><span class="p">()</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The <a class="reference internal" href="#profile.Profile" title="profile.Profile"><code class="xref py py-class docutils literal notranslate"><span class="pre">Profile</span></code></a> class can also be used as a context manager (supported
|
||
only in <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a> module. see <a class="reference internal" href="stdtypes.html#typecontextmanager"><span class="std std-ref">Context Manager Types</span></a>):</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">cProfile</span>
|
||
|
||
<span class="k">with</span> <span class="n">cProfile</span><span class="o">.</span><span class="n">Profile</span><span class="p">()</span> <span class="k">as</span> <span class="n">pr</span><span class="p">:</span>
|
||
<span class="c1"># ... do something ...</span>
|
||
|
||
<span class="n">pr</span><span class="o">.</span><span class="n">print_stats</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="versionchanged">
|
||
<p><span class="versionmodified changed">Changed in version 3.8: </span>Added context manager support.</p>
|
||
</div>
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="profile.Profile.enable">
|
||
<span class="sig-name descname"><span class="pre">enable</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile.enable" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Start collecting profiling data. Only in <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="profile.Profile.disable">
|
||
<span class="sig-name descname"><span class="pre">disable</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile.disable" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Stop collecting profiling data. Only in <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="profile.Profile.create_stats">
|
||
<span class="sig-name descname"><span class="pre">create_stats</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile.create_stats" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Stop collecting profiling data and record the results internally
|
||
as the current profile.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="profile.Profile.print_stats">
|
||
<span class="sig-name descname"><span class="pre">print_stats</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sort</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">-1</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile.print_stats" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Create a <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> object based on the current
|
||
profile and print the results to stdout.</p>
|
||
<p>The <em>sort</em> parameter specifies the sorting order of the displayed
|
||
statistics. It accepts a single key or a tuple of keys to enable
|
||
multi-level sorting, as in <a class="reference internal" href="#pstats.Stats.sort_stats" title="pstats.Stats.sort_stats"><code class="xref py py-func docutils literal notranslate"><span class="pre">Stats.sort_stats</span></code></a>.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.13: </span><a class="reference internal" href="#profile.Profile.print_stats" title="profile.Profile.print_stats"><code class="xref py py-meth docutils literal notranslate"><span class="pre">print_stats()</span></code></a> now accepts a tuple of keys.</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="profile.Profile.dump_stats">
|
||
<span class="sig-name descname"><span class="pre">dump_stats</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">filename</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile.dump_stats" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Write the results of the current profile to <em>filename</em>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="profile.Profile.run">
|
||
<span class="sig-name descname"><span class="pre">run</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cmd</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile.run" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Profile the cmd via <a class="reference internal" href="functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="profile.Profile.runctx">
|
||
<span class="sig-name descname"><span class="pre">runctx</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cmd</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">globals</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">locals</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile.runctx" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Profile the cmd via <a class="reference internal" href="functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a> with the specified global and
|
||
local environment.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="profile.Profile.runcall">
|
||
<span class="sig-name descname"><span class="pre">runcall</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">func</span></span></em>, <em class="sig-param"><span class="positional-only-separator o"><abbr title="Positional-only parameter separator (PEP 570)"><span class="pre">/</span></abbr></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#profile.Profile.runcall" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Profile <code class="docutils literal notranslate"><span class="pre">func(*args,</span> <span class="pre">**kwargs)</span></code></p>
|
||
</dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
<p>Note that profiling will only work if the called command/function actually
|
||
returns. If the interpreter is terminated (e.g. via a <a class="reference internal" href="sys.html#sys.exit" title="sys.exit"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.exit()</span></code></a> call
|
||
during the called command/function execution) no profiling results will be
|
||
printed.</p>
|
||
</section>
|
||
<section id="the-stats-class">
|
||
<span id="profile-stats"></span><h2>The <code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code> Class<a class="headerlink" href="#the-stats-class" title="Link to this heading">¶</a></h2>
|
||
<p>Analysis of the profiler data is done using the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> class.</p>
|
||
<dl class="py class" id="module-pstats">
|
||
<dt class="sig sig-object py" id="pstats.Stats">
|
||
<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">pstats.</span></span><span class="sig-name descname"><span class="pre">Stats</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">*filenames</span> <span class="pre">or</span> <span class="pre">profile</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stream=sys.stdout</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This class constructor creates an instance of a “statistics object” from a
|
||
<em>filename</em> (or list of filenames) or from a <code class="xref py py-class docutils literal notranslate"><span class="pre">Profile</span></code> instance. Output
|
||
will be printed to the stream specified by <em>stream</em>.</p>
|
||
<p>The file selected by the above constructor must have been created by the
|
||
corresponding version of <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> or <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a>. To be specific,
|
||
there is <em>no</em> file compatibility guaranteed with future versions of this
|
||
profiler, and there is no compatibility with files produced by other
|
||
profilers, or the same profiler run on a different operating system. If
|
||
several files are provided, all the statistics for identical functions will
|
||
be coalesced, so that an overall view of several processes can be considered
|
||
in a single report. If additional files need to be combined with data in an
|
||
existing <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> object, the <a class="reference internal" href="#pstats.Stats.add" title="pstats.Stats.add"><code class="xref py py-meth docutils literal notranslate"><span class="pre">add()</span></code></a> method
|
||
can be used.</p>
|
||
<p>Instead of reading the profile data from a file, a <code class="xref py py-class docutils literal notranslate"><span class="pre">cProfile.Profile</span></code>
|
||
or <a class="reference internal" href="#profile.Profile" title="profile.Profile"><code class="xref py py-class docutils literal notranslate"><span class="pre">profile.Profile</span></code></a> object can be used as the profile data source.</p>
|
||
<p><a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> objects have the following methods:</p>
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.strip_dirs">
|
||
<span class="sig-name descname"><span class="pre">strip_dirs</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.strip_dirs" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This method for the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> class removes all leading path
|
||
information from file names. It is very useful in reducing the size of
|
||
the printout to fit within (close to) 80 columns. This method modifies
|
||
the object, and the stripped information is lost. After performing a
|
||
strip operation, the object is considered to have its entries in a
|
||
“random” order, as it was just after object initialization and loading.
|
||
If <a class="reference internal" href="#pstats.Stats.strip_dirs" title="pstats.Stats.strip_dirs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">strip_dirs()</span></code></a> causes two function names to be
|
||
indistinguishable (they are on the same line of the same filename, and
|
||
have the same function name), then the statistics for these two entries
|
||
are accumulated into a single entry.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.add">
|
||
<span class="sig-name descname"><span class="pre">add</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">filenames</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.add" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This method of the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> class accumulates additional profiling
|
||
information into the current profiling object. Its arguments should refer
|
||
to filenames created by the corresponding version of <a class="reference internal" href="#profile.run" title="profile.run"><code class="xref py py-func docutils literal notranslate"><span class="pre">profile.run()</span></code></a>
|
||
or <code class="xref py py-func docutils literal notranslate"><span class="pre">cProfile.run()</span></code>. Statistics for identically named (re: file, line,
|
||
name) functions are automatically accumulated into single function
|
||
statistics.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.dump_stats">
|
||
<span class="sig-name descname"><span class="pre">dump_stats</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">filename</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.dump_stats" title="Link to this definition">¶</a></dt>
|
||
<dd><p>Save the data loaded into the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> object to a file named
|
||
<em>filename</em>. The file is created if it does not exist, and is overwritten
|
||
if it already exists. This is equivalent to the method of the same name
|
||
on the <a class="reference internal" href="#profile.Profile" title="profile.Profile"><code class="xref py py-class docutils literal notranslate"><span class="pre">profile.Profile</span></code></a> and <code class="xref py py-class docutils literal notranslate"><span class="pre">cProfile.Profile</span></code> classes.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.sort_stats">
|
||
<span class="sig-name descname"><span class="pre">sort_stats</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">keys</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.sort_stats" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This method modifies the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> object by sorting it according to
|
||
the supplied criteria. The argument can be either a string or a SortKey
|
||
enum identifying the basis of a sort (example: <code class="docutils literal notranslate"><span class="pre">'time'</span></code>, <code class="docutils literal notranslate"><span class="pre">'name'</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">SortKey.TIME</span></code> or <code class="docutils literal notranslate"><span class="pre">SortKey.NAME</span></code>). The SortKey enums argument have
|
||
advantage over the string argument in that it is more robust and less
|
||
error prone.</p>
|
||
<p>When more than one key is provided, then additional keys are used as
|
||
secondary criteria when there is equality in all keys selected before
|
||
them. For example, <code class="docutils literal notranslate"><span class="pre">sort_stats(SortKey.NAME,</span> <span class="pre">SortKey.FILE)</span></code> will sort
|
||
all the entries according to their function name, and resolve all ties
|
||
(identical function names) by sorting by file name.</p>
|
||
<p>For the string argument, abbreviations can be used for any key names, as
|
||
long as the abbreviation is unambiguous.</p>
|
||
<p>The following are the valid string and SortKey:</p>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Valid String Arg</p></th>
|
||
<th class="head"><p>Valid enum Arg</p></th>
|
||
<th class="head"><p>Meaning</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'calls'</span></code></p></td>
|
||
<td><p>SortKey.CALLS</p></td>
|
||
<td><p>call count</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'cumulative'</span></code></p></td>
|
||
<td><p>SortKey.CUMULATIVE</p></td>
|
||
<td><p>cumulative time</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'cumtime'</span></code></p></td>
|
||
<td><p>N/A</p></td>
|
||
<td><p>cumulative time</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'file'</span></code></p></td>
|
||
<td><p>N/A</p></td>
|
||
<td><p>file name</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'filename'</span></code></p></td>
|
||
<td><p>SortKey.FILENAME</p></td>
|
||
<td><p>file name</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'module'</span></code></p></td>
|
||
<td><p>N/A</p></td>
|
||
<td><p>file name</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'ncalls'</span></code></p></td>
|
||
<td><p>N/A</p></td>
|
||
<td><p>call count</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'pcalls'</span></code></p></td>
|
||
<td><p>SortKey.PCALLS</p></td>
|
||
<td><p>primitive call count</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'line'</span></code></p></td>
|
||
<td><p>SortKey.LINE</p></td>
|
||
<td><p>line number</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'name'</span></code></p></td>
|
||
<td><p>SortKey.NAME</p></td>
|
||
<td><p>function name</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'nfl'</span></code></p></td>
|
||
<td><p>SortKey.NFL</p></td>
|
||
<td><p>name/file/line</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'stdname'</span></code></p></td>
|
||
<td><p>SortKey.STDNAME</p></td>
|
||
<td><p>standard name</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">'time'</span></code></p></td>
|
||
<td><p>SortKey.TIME</p></td>
|
||
<td><p>internal time</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">'tottime'</span></code></p></td>
|
||
<td><p>N/A</p></td>
|
||
<td><p>internal time</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Note that all sorts on statistics are in descending order (placing most
|
||
time consuming items first), where as name, file, and line number searches
|
||
are in ascending order (alphabetical). The subtle distinction between
|
||
<code class="docutils literal notranslate"><span class="pre">SortKey.NFL</span></code> and <code class="docutils literal notranslate"><span class="pre">SortKey.STDNAME</span></code> is that the standard name is a
|
||
sort of the name as printed, which means that the embedded line numbers
|
||
get compared in an odd way. For example, lines 3, 20, and 40 would (if
|
||
the file names were the same) appear in the string order 20, 3 and 40.
|
||
In contrast, <code class="docutils literal notranslate"><span class="pre">SortKey.NFL</span></code> does a numeric compare of the line numbers.
|
||
In fact, <code class="docutils literal notranslate"><span class="pre">sort_stats(SortKey.NFL)</span></code> is the same as
|
||
<code class="docutils literal notranslate"><span class="pre">sort_stats(SortKey.NAME,</span> <span class="pre">SortKey.FILENAME,</span> <span class="pre">SortKey.LINE)</span></code>.</p>
|
||
<p>For backward-compatibility reasons, the numeric arguments <code class="docutils literal notranslate"><span class="pre">-1</span></code>, <code class="docutils literal notranslate"><span class="pre">0</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">1</span></code>, and <code class="docutils literal notranslate"><span class="pre">2</span></code> are permitted. They are interpreted as <code class="docutils literal notranslate"><span class="pre">'stdname'</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">'calls'</span></code>, <code class="docutils literal notranslate"><span class="pre">'time'</span></code>, and <code class="docutils literal notranslate"><span class="pre">'cumulative'</span></code> respectively. If this old
|
||
style format (numeric) is used, only one sort key (the numeric key) will
|
||
be used, and additional arguments will be silently ignored.</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.7: </span>Added the SortKey enum.</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.reverse_order">
|
||
<span class="sig-name descname"><span class="pre">reverse_order</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.reverse_order" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This method for the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> class reverses the ordering of the
|
||
basic list within the object. Note that by default ascending vs
|
||
descending order is properly selected based on the sort key of choice.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.print_stats">
|
||
<span class="sig-name descname"><span class="pre">print_stats</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">restrictions</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.print_stats" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This method for the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> class prints out a report as described
|
||
in the <a class="reference internal" href="#profile.run" title="profile.run"><code class="xref py py-func docutils literal notranslate"><span class="pre">profile.run()</span></code></a> definition.</p>
|
||
<p>The order of the printing is based on the last
|
||
<a class="reference internal" href="#pstats.Stats.sort_stats" title="pstats.Stats.sort_stats"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sort_stats()</span></code></a> operation done on the object (subject to
|
||
caveats in <a class="reference internal" href="#pstats.Stats.add" title="pstats.Stats.add"><code class="xref py py-meth docutils literal notranslate"><span class="pre">add()</span></code></a> and
|
||
<a class="reference internal" href="#pstats.Stats.strip_dirs" title="pstats.Stats.strip_dirs"><code class="xref py py-meth docutils literal notranslate"><span class="pre">strip_dirs()</span></code></a>).</p>
|
||
<p>The arguments provided (if any) can be used to limit the list down to the
|
||
significant entries. Initially, the list is taken to be the complete set
|
||
of profiled functions. Each restriction is either an integer (to select a
|
||
count of lines), or a decimal fraction between 0.0 and 1.0 inclusive (to
|
||
select a percentage of lines), or a string that will interpreted as a
|
||
regular expression (to pattern match the standard name that is printed).
|
||
If several restrictions are provided, then they are applied sequentially.
|
||
For example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">print_stats</span><span class="p">(</span><span class="mf">.1</span><span class="p">,</span> <span class="s1">'foo:'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>would first limit the printing to first 10% of list, and then only print
|
||
functions that were part of filename <code class="file docutils literal notranslate"><span class="pre">.*foo:</span></code>. In contrast, the
|
||
command:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">print_stats</span><span class="p">(</span><span class="s1">'foo:'</span><span class="p">,</span> <span class="mf">.1</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>would limit the list to all functions having file names <code class="file docutils literal notranslate"><span class="pre">.*foo:</span></code>,
|
||
and then proceed to only print the first 10% of them.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.print_callers">
|
||
<span class="sig-name descname"><span class="pre">print_callers</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">restrictions</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.print_callers" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This method for the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> class prints a list of all functions
|
||
that called each function in the profiled database. The ordering is
|
||
identical to that provided by <a class="reference internal" href="#pstats.Stats.print_stats" title="pstats.Stats.print_stats"><code class="xref py py-meth docutils literal notranslate"><span class="pre">print_stats()</span></code></a>, and the
|
||
definition of the restricting argument is also identical. Each caller is
|
||
reported on its own line. The format differs slightly depending on the
|
||
profiler that produced the stats:</p>
|
||
<ul class="simple">
|
||
<li><p>With <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a>, a number is shown in parentheses after each caller
|
||
to show how many times this specific call was made. For convenience, a
|
||
second non-parenthesized number repeats the cumulative time spent in the
|
||
function at the right.</p></li>
|
||
<li><p>With <a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a>, each caller is preceded by three numbers: the
|
||
number of times this specific call was made, and the total and
|
||
cumulative times spent in the current function while it was invoked by
|
||
this specific caller.</p></li>
|
||
</ul>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.print_callees">
|
||
<span class="sig-name descname"><span class="pre">print_callees</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">restrictions</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.print_callees" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This method for the <a class="reference internal" href="#pstats.Stats" title="pstats.Stats"><code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code></a> class prints a list of all function
|
||
that were called by the indicated function. Aside from this reversal of
|
||
direction of calls (re: called vs was called by), the arguments and
|
||
ordering are identical to the <a class="reference internal" href="#pstats.Stats.print_callers" title="pstats.Stats.print_callers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">print_callers()</span></code></a> method.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="py method">
|
||
<dt class="sig sig-object py" id="pstats.Stats.get_stats_profile">
|
||
<span class="sig-name descname"><span class="pre">get_stats_profile</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#pstats.Stats.get_stats_profile" title="Link to this definition">¶</a></dt>
|
||
<dd><p>This method returns an instance of StatsProfile, which contains a mapping
|
||
of function names to instances of FunctionProfile. Each FunctionProfile
|
||
instance holds information related to the function’s profile such as how
|
||
long the function took to run, how many times it was called, etc…</p>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.9: </span>Added the following dataclasses: StatsProfile, FunctionProfile.
|
||
Added the following function: get_stats_profile.</p>
|
||
</div>
|
||
</dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
</section>
|
||
<section id="what-is-deterministic-profiling">
|
||
<span id="deterministic-profiling"></span><h2>What Is Deterministic Profiling?<a class="headerlink" href="#what-is-deterministic-profiling" title="Link to this heading">¶</a></h2>
|
||
<p><em class="dfn">Deterministic profiling</em> is meant to reflect the fact that all <em>function
|
||
call</em>, <em>function return</em>, and <em>exception</em> events are monitored, and precise
|
||
timings are made for the intervals between these events (during which time the
|
||
user’s code is executing). In contrast, <em class="dfn">statistical profiling</em> (which is
|
||
not done by this module) randomly samples the effective instruction pointer, and
|
||
deduces where time is being spent. The latter technique traditionally involves
|
||
less overhead (as the code does not need to be instrumented), but provides only
|
||
relative indications of where time is being spent.</p>
|
||
<p>In Python, since there is an interpreter active during execution, the presence
|
||
of instrumented code is not required in order to do deterministic profiling.
|
||
Python automatically provides a <em class="dfn">hook</em> (optional callback) for each event.
|
||
In addition, the interpreted nature of Python tends to add so much overhead to
|
||
execution, that deterministic profiling tends to only add small processing
|
||
overhead in typical applications. The result is that deterministic profiling is
|
||
not that expensive, yet provides extensive run time statistics about the
|
||
execution of a Python program.</p>
|
||
<p>Call count statistics can be used to identify bugs in code (surprising counts),
|
||
and to identify possible inline-expansion points (high call counts). Internal
|
||
time statistics can be used to identify “hot loops” that should be carefully
|
||
optimized. Cumulative time statistics should be used to identify high level
|
||
errors in the selection of algorithms. Note that the unusual handling of
|
||
cumulative times in this profiler allows statistics for recursive
|
||
implementations of algorithms to be directly compared to iterative
|
||
implementations.</p>
|
||
</section>
|
||
<section id="limitations">
|
||
<span id="profile-limitations"></span><h2>Limitations<a class="headerlink" href="#limitations" title="Link to this heading">¶</a></h2>
|
||
<p>One limitation has to do with accuracy of timing information. There is a
|
||
fundamental problem with deterministic profilers involving accuracy. The most
|
||
obvious restriction is that the underlying “clock” is only ticking at a rate
|
||
(typically) of about .001 seconds. Hence no measurements will be more accurate
|
||
than the underlying clock. If enough measurements are taken, then the “error”
|
||
will tend to average out. Unfortunately, removing this first error induces a
|
||
second source of error.</p>
|
||
<p>The second problem is that it “takes a while” from when an event is dispatched
|
||
until the profiler’s call to get the time actually <em>gets</em> the state of the
|
||
clock. Similarly, there is a certain lag when exiting the profiler event
|
||
handler from the time that the clock’s value was obtained (and then squirreled
|
||
away), until the user’s code is once again executing. As a result, functions
|
||
that are called many times, or call many functions, will typically accumulate
|
||
this error. The error that accumulates in this fashion is typically less than
|
||
the accuracy of the clock (less than one clock tick), but it <em>can</em> accumulate
|
||
and become very significant.</p>
|
||
<p>The problem is more important with <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> than with the lower-overhead
|
||
<a class="reference internal" href="#module-cProfile" title="cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code></a>. For this reason, <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> provides a means of
|
||
calibrating itself for a given platform so that this error can be
|
||
probabilistically (on the average) removed. After the profiler is calibrated, it
|
||
will be more accurate (in a least square sense), but it will sometimes produce
|
||
negative numbers (when call counts are exceptionally low, and the gods of
|
||
probability work against you :-). ) Do <em>not</em> be alarmed by negative numbers in
|
||
the profile. They should <em>only</em> appear if you have calibrated your profiler,
|
||
and the results are actually better than without calibration.</p>
|
||
</section>
|
||
<section id="calibration">
|
||
<span id="profile-calibration"></span><h2>Calibration<a class="headerlink" href="#calibration" title="Link to this heading">¶</a></h2>
|
||
<p>The profiler of the <a class="reference internal" href="#module-profile" title="profile: Python source profiler."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> module subtracts a constant from each event
|
||
handling time to compensate for the overhead of calling the time function, and
|
||
socking away the results. By default, the constant is 0. The following
|
||
procedure can be used to obtain a better constant for a given platform (see
|
||
<a class="reference internal" href="#profile-limitations"><span class="std std-ref">Limitations</span></a>).</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">profile</span>
|
||
<span class="n">pr</span> <span class="o">=</span> <span class="n">profile</span><span class="o">.</span><span class="n">Profile</span><span class="p">()</span>
|
||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">pr</span><span class="o">.</span><span class="n">calibrate</span><span class="p">(</span><span class="mi">10000</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The method executes the number of Python calls given by the argument, directly
|
||
and again under the profiler, measuring the time for both. It then computes the
|
||
hidden overhead per profiler event, and returns that as a float. For example,
|
||
on a 1.8Ghz Intel Core i5 running macOS, and using Python’s time.process_time() as
|
||
the timer, the magical number is about 4.04e-6.</p>
|
||
<p>The object of this exercise is to get a fairly consistent result. If your
|
||
computer is <em>very</em> fast, or your timer function has poor resolution, you might
|
||
have to pass 100000, or even 1000000, to get consistent results.</p>
|
||
<p>When you have a consistent answer, there are three ways you can use it:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">profile</span>
|
||
|
||
<span class="c1"># 1. Apply computed bias to all Profile instances created hereafter.</span>
|
||
<span class="n">profile</span><span class="o">.</span><span class="n">Profile</span><span class="o">.</span><span class="n">bias</span> <span class="o">=</span> <span class="n">your_computed_bias</span>
|
||
|
||
<span class="c1"># 2. Apply computed bias to a specific Profile instance.</span>
|
||
<span class="n">pr</span> <span class="o">=</span> <span class="n">profile</span><span class="o">.</span><span class="n">Profile</span><span class="p">()</span>
|
||
<span class="n">pr</span><span class="o">.</span><span class="n">bias</span> <span class="o">=</span> <span class="n">your_computed_bias</span>
|
||
|
||
<span class="c1"># 3. Specify computed bias in instance constructor.</span>
|
||
<span class="n">pr</span> <span class="o">=</span> <span class="n">profile</span><span class="o">.</span><span class="n">Profile</span><span class="p">(</span><span class="n">bias</span><span class="o">=</span><span class="n">your_computed_bias</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>If you have a choice, you are better off choosing a smaller constant, and then
|
||
your results will “less often” show up as negative in profile statistics.</p>
|
||
</section>
|
||
<section id="using-a-custom-timer">
|
||
<span id="profile-timers"></span><h2>Using a custom timer<a class="headerlink" href="#using-a-custom-timer" title="Link to this heading">¶</a></h2>
|
||
<p>If you want to change how current time is determined (for example, to force use
|
||
of wall-clock time or elapsed process time), pass the timing function you want
|
||
to the <code class="xref py py-class docutils literal notranslate"><span class="pre">Profile</span></code> class constructor:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">pr</span> <span class="o">=</span> <span class="n">profile</span><span class="o">.</span><span class="n">Profile</span><span class="p">(</span><span class="n">your_time_func</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The resulting profiler will then call <code class="docutils literal notranslate"><span class="pre">your_time_func</span></code>. Depending on whether
|
||
you are using <a class="reference internal" href="#profile.Profile" title="profile.Profile"><code class="xref py py-class docutils literal notranslate"><span class="pre">profile.Profile</span></code></a> or <code class="xref py py-class docutils literal notranslate"><span class="pre">cProfile.Profile</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">your_time_func</span></code>’s return value will be interpreted differently:</p>
|
||
<dl>
|
||
<dt><a class="reference internal" href="#profile.Profile" title="profile.Profile"><code class="xref py py-class docutils literal notranslate"><span class="pre">profile.Profile</span></code></a></dt><dd><p><code class="docutils literal notranslate"><span class="pre">your_time_func</span></code> should return a single number, or a list of numbers whose
|
||
sum is the current time (like what <a class="reference internal" href="os.html#os.times" title="os.times"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.times()</span></code></a> returns). If the
|
||
function returns a single time number, or the list of returned numbers has
|
||
length 2, then you will get an especially fast version of the dispatch
|
||
routine.</p>
|
||
<p>Be warned that you should calibrate the profiler class for the timer function
|
||
that you choose (see <a class="reference internal" href="#profile-calibration"><span class="std std-ref">Calibration</span></a>). For most machines, a timer
|
||
that returns a lone integer value will provide the best results in terms of
|
||
low overhead during profiling. (<a class="reference internal" href="os.html#os.times" title="os.times"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.times()</span></code></a> is <em>pretty</em> bad, as it
|
||
returns a tuple of floating-point values). If you want to substitute a
|
||
better timer in the cleanest fashion, derive a class and hardwire a
|
||
replacement dispatch method that best handles your timer call, along with the
|
||
appropriate calibration constant.</p>
|
||
</dd>
|
||
<dt><code class="xref py py-class docutils literal notranslate"><span class="pre">cProfile.Profile</span></code></dt><dd><p><code class="docutils literal notranslate"><span class="pre">your_time_func</span></code> should return a single number. If it returns integers,
|
||
you can also invoke the class constructor with a second argument specifying
|
||
the real duration of one unit of time. For example, if
|
||
<code class="docutils literal notranslate"><span class="pre">your_integer_time_func</span></code> returns times measured in thousands of seconds,
|
||
you would construct the <code class="xref py py-class docutils literal notranslate"><span class="pre">Profile</span></code> instance as follows:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">pr</span> <span class="o">=</span> <span class="n">cProfile</span><span class="o">.</span><span class="n">Profile</span><span class="p">(</span><span class="n">your_integer_time_func</span><span class="p">,</span> <span class="mf">0.001</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>As the <code class="xref py py-class docutils literal notranslate"><span class="pre">cProfile.Profile</span></code> class cannot be calibrated, custom timer
|
||
functions should be used with care and should be as fast as possible. For
|
||
the best results with a custom timer, it might be necessary to hard-code it
|
||
in the C source of the internal <code class="xref py py-mod docutils literal notranslate"><span class="pre">_lsprof</span></code> module.</p>
|
||
</dd>
|
||
</dl>
|
||
<p>Python 3.3 adds several new functions in <a class="reference internal" href="time.html#module-time" title="time: Time access and conversions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">time</span></code></a> that can be used to make
|
||
precise measurements of process or wall-clock time. For example, see
|
||
<a class="reference internal" href="time.html#time.perf_counter" title="time.perf_counter"><code class="xref py py-func docutils literal notranslate"><span class="pre">time.perf_counter()</span></code></a>.</p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
<div class="clearer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="Main">
|
||
<div class="sphinxsidebarwrapper">
|
||
<div>
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">The Python Profilers</a><ul>
|
||
<li><a class="reference internal" href="#introduction-to-the-profilers">Introduction to the profilers</a></li>
|
||
<li><a class="reference internal" href="#instant-user-s-manual">Instant User’s Manual</a></li>
|
||
<li><a class="reference internal" href="#module-cProfile"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code> and <code class="xref py py-mod docutils literal notranslate"><span class="pre">cProfile</span></code> Module Reference</a></li>
|
||
<li><a class="reference internal" href="#the-stats-class">The <code class="xref py py-class docutils literal notranslate"><span class="pre">Stats</span></code> Class</a></li>
|
||
<li><a class="reference internal" href="#what-is-deterministic-profiling">What Is Deterministic Profiling?</a></li>
|
||
<li><a class="reference internal" href="#limitations">Limitations</a></li>
|
||
<li><a class="reference internal" href="#calibration">Calibration</a></li>
|
||
<li><a class="reference internal" href="#using-a-custom-timer">Using a custom timer</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
<div>
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="pdb.html"
|
||
title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">pdb</span></code> — The Python Debugger</a></p>
|
||
</div>
|
||
<div>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="timeit.html"
|
||
title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">timeit</span></code> — Measure execution time of small code snippets</a></p>
|
||
</div>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/main/Doc/library/profile.rst"
|
||
rel="nofollow">Show Source
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div id="sidebarbutton" title="Collapse sidebar">
|
||
<span>«</span>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="Related">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="timeit.html" title="timeit — Measure execution time of small code snippets"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="pdb.html" title="pdb — The Python Debugger"
|
||
>previous</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.13.3 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="debug.html" >Debugging and Profiling</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">The Python Profilers</a></li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
<li class="right">
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label> |</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
©
|
||
<a href="../copyright.html">
|
||
|
||
Copyright
|
||
|
||
</a>
|
||
2001-2025, Python Software Foundation.
|
||
<br />
|
||
This page is licensed under the Python Software Foundation License Version 2.
|
||
<br />
|
||
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
|
||
<br />
|
||
|
||
See <a href="/license.html">History and License</a> for more information.<br />
|
||
|
||
|
||
<br />
|
||
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
<br />
|
||
Last updated on Apr 08, 2025 (14:33 UTC).
|
||
|
||
<a href="/bugs.html">Found a bug</a>?
|
||
|
||
<br />
|
||
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |