Skip to content

Commit 3002ab8

Browse files
committed
Add docs
1 parent f3dc377 commit 3002ab8

File tree

1 file changed

+198
-8
lines changed

1 file changed

+198
-8
lines changed

Doc/library/profile.rst

Lines changed: 198 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
The Python Profilers
55
********************
66

7-
**Source code:** :source:`Lib/profile.py` and :source:`Lib/pstats.py`
7+
**Source code:** :source:`Lib/profile.py`, :source:`Lib/pstats.py`, and :source:`Lib/profile/sample.py`
88

99
--------------
1010

@@ -14,23 +14,59 @@ Introduction to the profilers
1414
=============================
1515

1616
.. index::
17+
single: statistical profiling
18+
single: profiling, statistical
1719
single: deterministic profiling
1820
single: profiling, deterministic
1921

20-
:mod:`cProfile` and :mod:`profile` provide :dfn:`deterministic profiling` of
22+
Python provides both :dfn:`statistical profiling` and :dfn:`deterministic profiling` of
2123
Python programs. A :dfn:`profile` is a set of statistics that describes how
2224
often and for how long various parts of the program executed. These statistics
2325
can be formatted into reports via the :mod:`pstats` module.
2426

25-
The Python standard library provides two different implementations of the same
26-
profiling interface:
27+
**Profiler Comparison:**
28+
29+
+-------------------+----------------------+----------------------+----------------------+
30+
| Feature | Statistical | Deterministic | Deterministic |
31+
| | (``profile.sample``) | (``cProfile``) | (``profile``) |
32+
+===================+======================+======================+======================+
33+
| **Target** | Running process | Code you run | Code you run |
34+
+-------------------+----------------------+----------------------+----------------------+
35+
| **Overhead** | Virtually none | Moderate | High |
36+
+-------------------+----------------------+----------------------+----------------------+
37+
| **Accuracy** | Statistical approx. | Exact call counts | Exact call counts |
38+
+-------------------+----------------------+----------------------+----------------------+
39+
| **Setup** | Attach to any PID | Instrument code | Instrument code |
40+
+-------------------+----------------------+----------------------+----------------------+
41+
| **Use Case** | Production debugging | Development/testing | Profiler extension |
42+
+-------------------+----------------------+----------------------+----------------------+
43+
| **Implementation**| C extension | C extension | Pure Python |
44+
+-------------------+----------------------+----------------------+----------------------+
2745

28-
1. :mod:`cProfile` is recommended for most users; it's a C extension with
46+
.. note::
47+
48+
The statistical profiler (:mod:`profile.sample`) is recommended for most production
49+
use cases due to its extremely low overhead and ability to profile running processes
50+
without modification. It can attach to any Python process and collect performance
51+
data with minimal impact on execution speed, making it ideal for debugging
52+
performance issues in live applications.
53+
54+
The Python standard library provides three different profiling implementations:
55+
56+
**Statistical Profiler:**
57+
58+
1. :mod:`profile.sample` provides statistical profiling of running Python processes
59+
using periodic stack sampling. It can attach to any running Python process without
60+
requiring code modification or restart, making it ideal for production debugging.
61+
62+
**Deterministic Profilers:**
63+
64+
2. :mod:`cProfile` is recommended for development and testing; it's a C extension with
2965
reasonable overhead that makes it suitable for profiling long-running
3066
programs. Based on :mod:`lsprof`, contributed by Brett Rosen and Ted
3167
Czotter.
3268

33-
2. :mod:`profile`, a pure Python module whose interface is imitated by
69+
3. :mod:`profile`, a pure Python module whose interface is imitated by
3470
:mod:`cProfile`, but which adds significant overhead to profiled programs.
3571
If you're trying to extend the profiler in some way, the task might be easier
3672
with this module. Originally designed and written by Jim Roskind.
@@ -44,6 +80,22 @@ profiling interface:
4480
but not for C-level functions, and so the C code would seem faster than any
4581
Python one.
4682

83+
.. _statistical-profiling:
84+
85+
What Is Statistical Profiling?
86+
==============================
87+
88+
:dfn:`Statistical profiling` works by periodically interrupting a running program to capture its current call stack. Rather than monitoring every function entry and exit like deterministic profilers, it takes snapshots at regular intervals to build a statistical picture of where the program spends its time.
89+
90+
The sampling profiler uses process memory reading (via system calls like `process_vm_readv` on Linux, `vm_read` on macOS, and `ReadProcessMemory` on Windows) to attach to a running Python process and extract stack trace information without requiring any code modification or restart of the target process. This approach provides several key advantages over traditional profiling methods.
91+
92+
The fundamental principle is that if a function appears frequently in the collected stack samples, it is likely consuming significant CPU time. By analyzing thousands of samples, the profiler can accurately estimate the relative time spent in different parts of the program. The statistical nature means that while individual measurements may vary, the aggregate results converge to represent the true performance characteristics of the application.
93+
94+
Since statistical profiling operates externally to the target process, it introduces virtually no overhead to the running program. The profiler process runs separately and reads the target process memory without interrupting its execution. This makes it suitable for profiling production systems where performance impact must be minimized.
95+
96+
The accuracy of statistical profiling improves with the number of samples collected. Short-lived functions may be missed or underrepresented, while long-running functions will be captured proportionally to their execution time. This characteristic makes statistical profiling particularly effective for identifying the most significant performance bottlenecks rather than providing exhaustive coverage of all function calls.
97+
98+
Statistical profiling excels at answering questions like "which functions consume the most CPU time?" and "where should I focus optimization efforts?" rather than "exactly how many times was this function called?" The trade-off between precision and practicality makes it an invaluable tool for performance analysis in real-world applications.
4799

48100
.. _profile-instant:
49101

@@ -54,6 +106,18 @@ This section is provided for users that "don't want to read the manual." It
54106
provides a very brief overview, and allows a user to rapidly perform profiling
55107
on an existing application.
56108

109+
**Statistical Profiling (Recommended for Production):**
110+
111+
To profile an existing running process::
112+
113+
python -m profile.sample 1234
114+
115+
To profile with custom settings::
116+
117+
python -m profile.sample -i 50 -d 30 1234
118+
119+
**Deterministic Profiling (Development/Testing):**
120+
57121
To profile a function that takes a single argument, you can do::
58122

59123
import cProfile
@@ -121,8 +185,134 @@ results to a file by specifying a filename to the :func:`run` function::
121185
The :class:`pstats.Stats` class reads profile results from a file and formats
122186
them in various ways.
123187

188+
.. _sampling-profiler-cli:
189+
190+
Statistical Profiler Command Line Interface
191+
===========================================
192+
193+
.. program:: profile.sample
194+
195+
The :mod:`profile.sample` module can be invoked as a script to profile running processes::
196+
197+
python -m profile.sample [options] PID
198+
199+
**Basic Usage Examples:**
200+
201+
Profile process 1234 for 10 seconds with default settings::
202+
203+
python -m profile.sample 1234
204+
205+
Profile with custom interval and duration, save to file::
206+
207+
python -m profile.sample -i 50 -d 30 -o profile.stats 1234
208+
209+
Generate collapsed stacks for flamegraph::
210+
211+
python -m profile.sample --collapsed 1234
212+
213+
Profile all threads, sort by total time::
214+
215+
python -m profile.sample -a --sort-tottime 1234
216+
217+
Profile with real-time sampling statistics::
218+
219+
python -m profile.sample --realtime-stats 1234
220+
221+
**Command Line Options:**
222+
223+
.. option:: PID
224+
225+
Process ID of the Python process to profile (required)
226+
227+
.. option:: -i, --interval INTERVAL
228+
229+
Sampling interval in microseconds (default: 100)
230+
231+
.. option:: -d, --duration DURATION
232+
233+
Sampling duration in seconds (default: 10)
234+
235+
.. option:: -a, --all-threads
236+
237+
Sample all threads in the process instead of just the main thread
238+
239+
.. option:: --realtime-stats
240+
241+
Print real-time sampling statistics during profiling
242+
243+
.. option:: --pstats
244+
245+
Generate pstats output (default)
246+
247+
.. option:: --collapsed
248+
249+
Generate collapsed stack traces for flamegraphs
250+
251+
.. option:: -o, --outfile OUTFILE
252+
253+
Save output to a file
254+
255+
**Sorting Options (pstats format only):**
256+
257+
.. option:: --sort-nsamples
258+
259+
Sort by number of direct samples
260+
261+
.. option:: --sort-tottime
262+
263+
Sort by total time
264+
265+
.. option:: --sort-cumtime
266+
267+
Sort by cumulative time (default)
268+
269+
.. option:: --sort-sample-pct
270+
271+
Sort by sample percentage
272+
273+
.. option:: --sort-cumul-pct
274+
275+
Sort by cumulative sample percentage
276+
277+
.. option:: --sort-nsamples-cumul
278+
279+
Sort by cumulative samples
280+
281+
.. option:: --sort-name
282+
283+
Sort by function name
284+
285+
.. option:: -l, --limit LIMIT
286+
287+
Limit the number of rows in the output (default: 15)
288+
289+
.. option:: --no-summary
290+
291+
Disable the summary section in the output
292+
293+
**Understanding Statistical Profile Output:**
294+
295+
The statistical profiler produces output similar to deterministic profilers but with different column meanings::
296+
297+
Profile Stats:
298+
nsamples sample% tottime (ms) cumul% cumtime (ms) filename:lineno(function)
299+
45/67 12.5 23.450 18.6 56.780 mymodule.py:42(process_data)
300+
23/23 6.4 15.230 6.4 15.230 <built-in>:0(len)
301+
302+
**Column Meanings:**
303+
304+
- **nsamples**: `direct/cumulative` - Times function was directly executing / on call stack
305+
- **sample%**: Percentage of total samples where function was directly executing
306+
- **tottime**: Estimated time spent directly in this function
307+
- **cumul%**: Percentage of samples where function was anywhere on call stack
308+
- **cumtime**: Estimated cumulative time including called functions
309+
- **filename:lineno(function)**: Location and name of the function
310+
124311
.. _profile-cli:
125312

313+
Deterministic Profiler Command Line Interface
314+
=============================================
315+
126316
.. program:: cProfile
127317

128318
The files :mod:`cProfile` and :mod:`profile` can also be invoked as a script to
@@ -564,7 +754,7 @@ What Is Deterministic Profiling?
564754
call*, *function return*, and *exception* events are monitored, and precise
565755
timings are made for the intervals between these events (during which time the
566756
user's code is executing). In contrast, :dfn:`statistical profiling` (which is
567-
not done by this module) randomly samples the effective instruction pointer, and
757+
provided by the :mod:`profile.sample` module) periodically samples the effective instruction pointer, and
568758
deduces where time is being spent. The latter technique traditionally involves
569759
less overhead (as the code does not need to be instrumented), but provides only
570760
relative indications of where time is being spent.
@@ -712,4 +902,4 @@ you are using :class:`profile.Profile` or :class:`cProfile.Profile`,
712902

713903
Python 3.3 adds several new functions in :mod:`time` that can be used to make
714904
precise measurements of process or wall-clock time. For example, see
715-
:func:`time.perf_counter`.
905+
:func:`time.perf_counter`.

0 commit comments

Comments
 (0)