617 lines
37 KiB
HTML
617 lines
37 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="profiling — Python profilers" />
|
||
<meta property="og:type" content="website" />
|
||
<meta property="og:url" content="https://docs.python.org/3/library/profiling.html" />
|
||
<meta property="og:site_name" content="Python documentation" />
|
||
<meta property="og:description" content="Source code: Lib/profiling/ Introduction to profiling: A profile is a set of statistics that describes how often and for how long various parts of a program execute. These statistics help identify ..." />
|
||
<meta property="og:image" content="_static/og-image.png" />
|
||
<meta property="og:image:alt" content="Python documentation" />
|
||
<meta name="description" content="Source code: Lib/profiling/ Introduction to profiling: A profile is a set of statistics that describes how often and for how long various parts of a program execute. These statistics help identify ..." />
|
||
<meta name="theme-color" content="#3776ab">
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
|
||
<title>profiling — Python profilers — Python 3.15.0 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/classic.css?v=234b1a7c" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=48df1187" />
|
||
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=0fc419ee" />
|
||
|
||
<script src="../_static/documentation_options.js?v=0fe728b1"></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.15.0 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="profiling.tracing — Deterministic profiler" href="profiling.tracing.html" />
|
||
<link rel="prev" title="pdb — The Python Debugger" href="pdb.html" />
|
||
|
||
|
||
<link rel="canonical" href="https://docs.python.org/3/library/profiling.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="#"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling</span></code> — Python profilers</a><ul>
|
||
<li><a class="reference internal" href="#introduction-to-profiling">Introduction to profiling</a></li>
|
||
<li><a class="reference internal" href="#choosing-a-profiler">Choosing a profiler</a><ul>
|
||
<li><a class="reference internal" href="#when-to-use-statistical-sampling">When to use statistical sampling</a></li>
|
||
<li><a class="reference internal" href="#when-to-use-deterministic-tracing">When to use deterministic tracing</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#quick-start">Quick start</a><ul>
|
||
<li><a class="reference internal" href="#statistical-profiling">Statistical profiling</a></li>
|
||
<li><a class="reference internal" href="#deterministic-profiling">Deterministic profiling</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#understanding-profile-output">Understanding profile output</a></li>
|
||
<li><a class="reference internal" href="#legacy-compatibility">Legacy compatibility</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="profiling.tracing.html"
|
||
title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code> — Deterministic profiler</a></p>
|
||
</div>
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
const title = document.querySelector('meta[property="og:title"]').content;
|
||
const elements = document.querySelectorAll('.improvepage');
|
||
const pageurl = window.location.href.split('?')[0];
|
||
elements.forEach(element => {
|
||
const url = new URL(element.href.split('?')[0].replace("-nojs", ""));
|
||
url.searchParams.set('pagetitle', title);
|
||
url.searchParams.set('pageurl', pageurl);
|
||
url.searchParams.set('pagesource', "library/profiling.rst");
|
||
element.href = url.toString();
|
||
});
|
||
});
|
||
</script>
|
||
<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 class="improvepage" href="../improve-page-nojs.html">Improve this page</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.15/Doc/library/profiling.rst?plain=1"
|
||
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="profiling.tracing.html" title="profiling.tracing — Deterministic profiler"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="pdb.html" title="pdb — The Python Debugger"
|
||
accesskey="P">previous</a> |</li>
|
||
|
||
<li class="root-icon"><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.15.0 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=""><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling</span></code> — 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="module-profiling">
|
||
<span id="profiling-python-profilers"></span><span id="profiling-module"></span><h1><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling</span></code> — Python profilers<a class="headerlink" href="#module-profiling" title="Link to this heading">¶</a></h1>
|
||
<div class="versionadded">
|
||
<p><span class="versionmodified added">Added in version 3.15.</span></p>
|
||
</div>
|
||
<p><strong>Source code:</strong> <a class="extlink-source reference external" href="https://github.com/python/cpython/tree/3.15/Lib/profiling/">Lib/profiling/</a></p>
|
||
<hr class="docutils" />
|
||
<section id="introduction-to-profiling">
|
||
<span id="index-0"></span><h2>Introduction to profiling<a class="headerlink" href="#introduction-to-profiling" title="Link to this heading">¶</a></h2>
|
||
<p>A <em class="dfn">profile</em> is a set of statistics that describes how often and for how
|
||
long various parts of a program execute. These statistics help identify
|
||
performance bottlenecks and guide optimization efforts. Python provides two
|
||
fundamentally different approaches to collecting this information: statistical
|
||
sampling and deterministic tracing.</p>
|
||
<p>The <code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling</span></code> package organizes Python’s built-in profiling tools under
|
||
a single namespace. It contains two submodules, each implementing a different
|
||
profiling methodology:</p>
|
||
<dl class="simple">
|
||
<dt><a class="reference internal" href="profiling.sampling.html#module-profiling.sampling" title="profiling.sampling: Statistical sampling profiler for Python processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.sampling</span></code></a></dt><dd><p>A statistical profiler that periodically samples the call stack. Run scripts
|
||
directly or attach to running processes by PID. Provides multiple output
|
||
formats (flame graphs, heatmaps, Firefox Profiler), GIL analysis, GC tracking,
|
||
and multiple profiling modes (wall-clock, CPU, GIL) with virtually no overhead.</p>
|
||
</dd>
|
||
<dt><a class="reference internal" href="profiling.tracing.html#module-profiling.tracing" title="profiling.tracing: Deterministic tracing profiler for Python programs."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code></a></dt><dd><p>A deterministic profiler that traces every function call, return, and
|
||
exception event. Provides exact call counts and precise timing information,
|
||
capturing every invocation including very fast functions.</p>
|
||
</dd>
|
||
</dl>
|
||
<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 benchmarking, use the
|
||
<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> module, which provides reasonably accurate timing
|
||
measurements. This distinction is particularly important when comparing
|
||
Python code against C code: deterministic profilers introduce overhead for
|
||
Python code but not for C-level functions, which can skew comparisons.</p>
|
||
</div>
|
||
</section>
|
||
<section id="choosing-a-profiler">
|
||
<span id="id1"></span><h2>Choosing a profiler<a class="headerlink" href="#choosing-a-profiler" title="Link to this heading">¶</a></h2>
|
||
<p>For most performance analysis, use the statistical profiler
|
||
(<a class="reference internal" href="profiling.sampling.html#module-profiling.sampling" title="profiling.sampling: Statistical sampling profiler for Python processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.sampling</span></code></a>). It has minimal overhead, works for both development
|
||
and production, and provides rich visualization options including flame graphs,
|
||
heatmaps, GIL analysis, and more.</p>
|
||
<p>Use the deterministic profiler (<a class="reference internal" href="profiling.tracing.html#module-profiling.tracing" title="profiling.tracing: Deterministic tracing profiler for Python programs."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code></a>) when you need <strong>exact
|
||
call counts</strong> and cannot afford to miss any function calls. Since it instruments
|
||
every function call and return, it will capture even very fast functions that
|
||
complete between sampling intervals. The tradeoff is higher overhead.</p>
|
||
<p>The following table summarizes the key differences:</p>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Feature</p></th>
|
||
<th class="head"><p>Statistical sampling
|
||
(<a class="reference internal" href="profiling.sampling.html#module-profiling.sampling" title="profiling.sampling: Statistical sampling profiler for Python processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.sampling</span></code></a>)</p></th>
|
||
<th class="head"><p>Deterministic
|
||
(<a class="reference internal" href="profiling.tracing.html#module-profiling.tracing" title="profiling.tracing: Deterministic tracing profiler for Python programs."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code></a>)</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><strong>Overhead</strong></p></td>
|
||
<td><p>Virtually none</p></td>
|
||
<td><p>Moderate</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><strong>Accuracy</strong></p></td>
|
||
<td><p>Statistical estimate</p></td>
|
||
<td><p>Exact call counts</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><strong>Output formats</strong></p></td>
|
||
<td><p>pstats, flame graph, heatmap,
|
||
gecko, collapsed</p></td>
|
||
<td><p>pstats</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><strong>Profiling modes</strong></p></td>
|
||
<td><p>Wall-clock, CPU, GIL</p></td>
|
||
<td><p>Wall-clock</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><strong>Special frames</strong></p></td>
|
||
<td><p>GC, native (C extensions)</p></td>
|
||
<td><p>N/A</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><strong>Attach to PID</strong></p></td>
|
||
<td><p>Yes</p></td>
|
||
<td><p>No</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<section id="when-to-use-statistical-sampling">
|
||
<h3>When to use statistical sampling<a class="headerlink" href="#when-to-use-statistical-sampling" title="Link to this heading">¶</a></h3>
|
||
<p>The statistical profiler (<a class="reference internal" href="profiling.sampling.html#module-profiling.sampling" title="profiling.sampling: Statistical sampling profiler for Python processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.sampling</span></code></a>) is recommended for most
|
||
performance analysis tasks. Use it the same way you would use
|
||
<a class="reference internal" href="profiling.tracing.html#module-profiling.tracing" title="profiling.tracing: Deterministic tracing profiler for Python programs."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code></a>:</p>
|
||
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>python<span class="w"> </span>-m<span class="w"> </span>profiling.sampling<span class="w"> </span>run<span class="w"> </span>script.py
|
||
</pre></div>
|
||
</div>
|
||
<p>One of the main strengths of the sampling profiler is its variety of output
|
||
formats. Beyond traditional pstats tables, it can generate interactive
|
||
flame graphs that visualize call hierarchies, line-level source heatmaps that
|
||
show exactly where time is spent in your code, and Firefox Profiler output for
|
||
timeline-based analysis.</p>
|
||
<p>The profiler also provides insight into Python interpreter behavior that
|
||
deterministic profiling cannot capture. Use <code class="docutils literal notranslate"><span class="pre">--mode</span> <span class="pre">gil</span></code> to identify GIL
|
||
contention in multi-threaded code, <code class="docutils literal notranslate"><span class="pre">--mode</span> <span class="pre">cpu</span></code> to measure actual CPU time
|
||
excluding I/O waits, or inspect <code class="docutils literal notranslate"><span class="pre"><GC></span></code> frames to understand garbage collection
|
||
overhead. The <code class="docutils literal notranslate"><span class="pre">--native</span></code> option reveals time spent in C extensions, helping
|
||
distinguish Python overhead from library performance.</p>
|
||
<p>For multi-threaded applications, the <code class="docutils literal notranslate"><span class="pre">-a</span></code> option samples all threads
|
||
simultaneously, showing how work is distributed. And for production debugging,
|
||
the <code class="docutils literal notranslate"><span class="pre">attach</span></code> command connects to any running Python process by PID without
|
||
requiring a restart or code changes.</p>
|
||
</section>
|
||
<section id="when-to-use-deterministic-tracing">
|
||
<h3>When to use deterministic tracing<a class="headerlink" href="#when-to-use-deterministic-tracing" title="Link to this heading">¶</a></h3>
|
||
<p>The deterministic profiler (<a class="reference internal" href="profiling.tracing.html#module-profiling.tracing" title="profiling.tracing: Deterministic tracing profiler for Python programs."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code></a>) instruments every function
|
||
call and return. This approach has higher overhead than sampling, but guarantees
|
||
complete coverage of program execution.</p>
|
||
<p>The primary reason to choose deterministic tracing is when you need exact call
|
||
counts. Statistical profiling estimates frequency based on sampling, which may
|
||
undercount short-lived functions that complete between samples. If you need to
|
||
verify that an optimization actually reduced the number of function calls, or
|
||
if you want to trace the complete call graph to understand caller-callee
|
||
relationships, deterministic tracing is the right choice.</p>
|
||
<p>Deterministic tracing also excels at capturing functions that execute in
|
||
microseconds. Such functions may not appear frequently enough in statistical
|
||
samples, but deterministic tracing records every invocation regardless of
|
||
duration.</p>
|
||
</section>
|
||
</section>
|
||
<section id="quick-start">
|
||
<h2>Quick start<a class="headerlink" href="#quick-start" title="Link to this heading">¶</a></h2>
|
||
<p>This section provides the minimal steps needed to start profiling. For complete
|
||
documentation, see the dedicated pages for each profiler.</p>
|
||
<section id="statistical-profiling">
|
||
<h3>Statistical profiling<a class="headerlink" href="#statistical-profiling" title="Link to this heading">¶</a></h3>
|
||
<p>To profile a script, use the <a class="reference internal" href="profiling.sampling.html#module-profiling.sampling" title="profiling.sampling: Statistical sampling profiler for Python processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.sampling</span></code></a> module with the <code class="docutils literal notranslate"><span class="pre">run</span></code>
|
||
command:</p>
|
||
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>python<span class="w"> </span>-m<span class="w"> </span>profiling.sampling<span class="w"> </span>run<span class="w"> </span>script.py
|
||
python<span class="w"> </span>-m<span class="w"> </span>profiling.sampling<span class="w"> </span>run<span class="w"> </span>-m<span class="w"> </span>mypackage.module
|
||
</pre></div>
|
||
</div>
|
||
<p>This runs the script under the profiler and prints a summary of where time was
|
||
spent. For an interactive flame graph:</p>
|
||
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>python<span class="w"> </span>-m<span class="w"> </span>profiling.sampling<span class="w"> </span>run<span class="w"> </span>--flamegraph<span class="w"> </span>script.py
|
||
</pre></div>
|
||
</div>
|
||
<p>To profile an already-running process, use the <code class="docutils literal notranslate"><span class="pre">attach</span></code> command with the
|
||
process ID:</p>
|
||
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>python<span class="w"> </span>-m<span class="w"> </span>profiling.sampling<span class="w"> </span>attach<span class="w"> </span><span class="m">1234</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>For custom settings, specify the sampling interval (in microseconds) and
|
||
duration (in seconds):</p>
|
||
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>python<span class="w"> </span>-m<span class="w"> </span>profiling.sampling<span class="w"> </span>run<span class="w"> </span>-i<span class="w"> </span><span class="m">50</span><span class="w"> </span>-d<span class="w"> </span><span class="m">30</span><span class="w"> </span>script.py
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="deterministic-profiling">
|
||
<h3>Deterministic profiling<a class="headerlink" href="#deterministic-profiling" title="Link to this heading">¶</a></h3>
|
||
<p>To profile a script from the command line:</p>
|
||
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>python<span class="w"> </span>-m<span class="w"> </span>profiling.tracing<span class="w"> </span>script.py
|
||
</pre></div>
|
||
</div>
|
||
<p>To profile a piece of code programmatically:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">profiling.tracing</span>
|
||
<span class="n">profiling</span><span class="o">.</span><span class="n">tracing</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s1">'my_function()'</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This executes the given code under the profiler and prints a summary showing
|
||
exact function call counts and timing.</p>
|
||
</section>
|
||
</section>
|
||
<section id="understanding-profile-output">
|
||
<span id="profile-output"></span><h2>Understanding profile output<a class="headerlink" href="#understanding-profile-output" title="Link to this heading">¶</a></h2>
|
||
<p>Both profilers collect function-level statistics, though they present them in
|
||
different formats. The sampling profiler offers multiple visualizations
|
||
(flame graphs, heatmaps, Firefox Profiler, pstats tables), while the
|
||
deterministic profiler produces pstats-compatible output. Regardless of format,
|
||
the underlying concepts are the same.</p>
|
||
<p>Key profiling concepts:</p>
|
||
<dl class="simple">
|
||
<dt><strong>Direct time</strong> (also called <em>self time</em> or <em>tottime</em>)</dt><dd><p>Time spent executing code in the function itself, excluding time spent in
|
||
functions it called. High direct time indicates the function contains
|
||
expensive operations.</p>
|
||
</dd>
|
||
<dt><strong>Cumulative time</strong> (also called <em>total time</em> or <em>cumtime</em>)</dt><dd><p>Time spent in the function and all functions it called. This measures the
|
||
total cost of calling a function, including its entire call subtree.</p>
|
||
</dd>
|
||
<dt><strong>Call count</strong> (also called <em>ncalls</em> or <em>samples</em>)</dt><dd><p>How many times the function was called (deterministic) or sampled
|
||
(statistical). In deterministic profiling, this is exact. In statistical
|
||
profiling, it represents the number of times the function appeared in a
|
||
stack sample.</p>
|
||
</dd>
|
||
<dt><strong>Primitive calls</strong></dt><dd><p>Calls that are not induced by recursion. When a function recurses, the total
|
||
call count includes recursive invocations, but primitive calls counts only
|
||
the initial entry. Displayed as <code class="docutils literal notranslate"><span class="pre">total/primitive</span></code> (for example, <code class="docutils literal notranslate"><span class="pre">3/1</span></code>
|
||
means three total calls, one primitive).</p>
|
||
</dd>
|
||
<dt><strong>Caller/Callee relationships</strong></dt><dd><p>Which functions called a given function (callers) and which functions it
|
||
called (callees). Flame graphs visualize this as nested rectangles; pstats
|
||
can display it via the <a class="reference internal" href="pstats.html#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> and
|
||
<a class="reference internal" href="pstats.html#pstats.Stats.print_callees" title="pstats.Stats.print_callees"><code class="xref py py-meth docutils literal notranslate"><span class="pre">print_callees()</span></code></a> methods.</p>
|
||
</dd>
|
||
</dl>
|
||
</section>
|
||
<section id="legacy-compatibility">
|
||
<h2>Legacy compatibility<a class="headerlink" href="#legacy-compatibility" title="Link to this heading">¶</a></h2>
|
||
<p>For backward compatibility, the <code class="docutils literal notranslate"><span class="pre">cProfile</span></code> module remains available as an
|
||
alias to <a class="reference internal" href="profiling.tracing.html#module-profiling.tracing" title="profiling.tracing: Deterministic tracing profiler for Python programs."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code></a>. Existing code using <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">cProfile</span></code> will
|
||
continue to work without modification in all future Python versions.</p>
|
||
<div class="deprecated">
|
||
<p><span class="versionmodified deprecated">Deprecated since version 3.15: </span>The pure Python <a class="reference internal" href="profile.html#module-profile" title="profile: Pure Python profiler (deprecated). (deprecated)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code></a> module is deprecated and will be removed in
|
||
Python 3.17. Use <a class="reference internal" href="profiling.tracing.html#module-profiling.tracing" title="profiling.tracing: Deterministic tracing profiler for Python programs."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code></a> (or its alias <code class="docutils literal notranslate"><span class="pre">cProfile</span></code>)
|
||
instead. See <code class="xref py py-mod docutils literal notranslate"><span class="pre">profile</span></code> for migration guidance.</p>
|
||
</div>
|
||
<div class="admonition seealso">
|
||
<p class="admonition-title">See also</p>
|
||
<dl class="simple">
|
||
<dt><a class="reference internal" href="profiling.sampling.html#module-profiling.sampling" title="profiling.sampling: Statistical sampling profiler for Python processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.sampling</span></code></a></dt><dd><p>Statistical sampling profiler with flame graphs, heatmaps, and GIL analysis.
|
||
Recommended for most users.</p>
|
||
</dd>
|
||
<dt><a class="reference internal" href="profiling.tracing.html#module-profiling.tracing" title="profiling.tracing: Deterministic tracing profiler for Python programs."><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code></a></dt><dd><p>Deterministic tracing profiler for exact call counts.</p>
|
||
</dd>
|
||
<dt><a class="reference internal" href="pstats.html#module-pstats" title="pstats: Statistics object for analyzing profiler output."><code class="xref py py-mod docutils literal notranslate"><span class="pre">pstats</span></code></a></dt><dd><p>Statistics analysis and formatting for profile data.</p>
|
||
</dd>
|
||
<dt><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></dt><dd><p>Module for measuring execution time of small code snippets.</p>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<p class="rubric">Submodules</p>
|
||
<div class="toctree-wrapper compound">
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="profiling.tracing.html"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code> — Deterministic profiler</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="profiling.sampling.html"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.sampling</span></code> — Statistical profiler</a></li>
|
||
</ul>
|
||
</div>
|
||
</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="#"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling</span></code> — Python profilers</a><ul>
|
||
<li><a class="reference internal" href="#introduction-to-profiling">Introduction to profiling</a></li>
|
||
<li><a class="reference internal" href="#choosing-a-profiler">Choosing a profiler</a><ul>
|
||
<li><a class="reference internal" href="#when-to-use-statistical-sampling">When to use statistical sampling</a></li>
|
||
<li><a class="reference internal" href="#when-to-use-deterministic-tracing">When to use deterministic tracing</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#quick-start">Quick start</a><ul>
|
||
<li><a class="reference internal" href="#statistical-profiling">Statistical profiling</a></li>
|
||
<li><a class="reference internal" href="#deterministic-profiling">Deterministic profiling</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#understanding-profile-output">Understanding profile output</a></li>
|
||
<li><a class="reference internal" href="#legacy-compatibility">Legacy compatibility</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="profiling.tracing.html"
|
||
title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling.tracing</span></code> — Deterministic profiler</a></p>
|
||
</div>
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
const title = document.querySelector('meta[property="og:title"]').content;
|
||
const elements = document.querySelectorAll('.improvepage');
|
||
const pageurl = window.location.href.split('?')[0];
|
||
elements.forEach(element => {
|
||
const url = new URL(element.href.split('?')[0].replace("-nojs", ""));
|
||
url.searchParams.set('pagetitle', title);
|
||
url.searchParams.set('pageurl', pageurl);
|
||
url.searchParams.set('pagesource', "library/profiling.rst");
|
||
element.href = url.toString();
|
||
});
|
||
});
|
||
</script>
|
||
<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 class="improvepage" href="../improve-page-nojs.html">Improve this page</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.15/Doc/library/profiling.rst?plain=1"
|
||
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="profiling.tracing.html" title="profiling.tracing — Deterministic profiler"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="pdb.html" title="pdb — The Python Debugger"
|
||
>previous</a> |</li>
|
||
|
||
<li class="root-icon"><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.15.0 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=""><code class="xref py py-mod docutils literal notranslate"><span class="pre">profiling</span></code> — 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 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 Oct 09, 2026 (11:35 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> |