From 994e22478d1a7d07fd8b67355fbd750361c4ba26 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:28:45 +0200 Subject: [PATCH 01/15] Set default code formatting to shell-session, not Python --- Doc/library/profiling-sampling.rst | 2 ++ Doc/library/profiling.rst | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Doc/library/profiling-sampling.rst b/Doc/library/profiling-sampling.rst index 8336d10c13c037..1a8b155b9072c3 100644 --- a/Doc/library/profiling-sampling.rst +++ b/Doc/library/profiling-sampling.rst @@ -1,3 +1,5 @@ +.. highlight:: shell-session + .. _profiling-sampling: *************************************************** diff --git a/Doc/library/profiling.rst b/Doc/library/profiling.rst index 57e5b4e4443e4e..b6d28969492259 100644 --- a/Doc/library/profiling.rst +++ b/Doc/library/profiling.rst @@ -1,3 +1,5 @@ +.. highlight:: shell-session + .. _profiling-module: *************************************** @@ -176,7 +178,9 @@ To profile a script from the command line:: python -m profiling.tracing myscript.py -To profile a piece of code programmatically:: +To profile a piece of code programmatically: + +.. code-block:: python import profiling.tracing profiling.tracing.run('my_function()') From c3573225471bd2c57c9d3a242d0373b51219ab7c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:30:04 +0200 Subject: [PATCH 02/15] Sentence case for headers --- Doc/library/profile.rst | 4 +-- Doc/library/profiling-sampling.rst | 56 +++++++++++++++--------------- Doc/library/profiling-tracing.rst | 14 ++++---- Doc/library/profiling.rst | 22 ++++++------ Doc/library/pstats.rst | 14 ++++---- 5 files changed, 55 insertions(+), 55 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 836399bff491a6..b48658bc0f290e 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -1,7 +1,7 @@ .. _profile: **************************************** -:mod:`!profile` --- Pure Python Profiler +:mod:`!profile` --- Pure Python profiler **************************************** .. module:: profile @@ -199,7 +199,7 @@ extend for custom profiling behavior. .. _deterministic-profiling: -What Is Deterministic Profiling? +What is deterministic profiling? ================================ :dfn:`Deterministic profiling` is meant to reflect the fact that all *function diff --git a/Doc/library/profiling-sampling.rst b/Doc/library/profiling-sampling.rst index 1a8b155b9072c3..97d145f1311087 100644 --- a/Doc/library/profiling-sampling.rst +++ b/Doc/library/profiling-sampling.rst @@ -3,7 +3,7 @@ .. _profiling-sampling: *************************************************** -:mod:`profiling.sampling` --- Statistical Profiler +:mod:`profiling.sampling` --- Statistical profiler *************************************************** .. module:: profiling.sampling @@ -28,7 +28,7 @@ process, overhead is virtually zero, making this profiler suitable for both development and production environments. -What Is Statistical Profiling? +What is statistical profiling? ============================== Statistical profiling builds a picture of program behavior by periodically @@ -64,7 +64,7 @@ deterministic profiling overhead would be unacceptable. For exact call counts and complete call graphs, use :mod:`profiling.tracing` instead. -Quick Examples +Quick examples ============== Profile a script and see the results immediately:: @@ -103,7 +103,7 @@ The profiler operates through two subcommands that determine how to obtain the target process. -The ``run`` Command +The ``run`` command ------------------- The ``run`` command launches a Python script or module and profiles it from @@ -121,7 +121,7 @@ profiled program:: python -m profiling.sampling run script.py --config settings.yaml -The ``attach`` Command +The ``attach`` command ---------------------- The ``attach`` command connects to an already-running Python process by its @@ -138,7 +138,7 @@ On most systems, attaching to another process requires appropriate permissions. On Linux, you may need to run as root or adjust the ``ptrace_scope`` setting. -Sampling Configuration +Sampling configuration ====================== Before exploring the various output formats and visualization options, it is @@ -171,7 +171,7 @@ The default configuration works well for most use cases: - No live statistics display during profiling -Sampling Interval and Duration +Sampling interval and duration ------------------------------ The two most fundamental parameters are the sampling interval and duration. @@ -200,7 +200,7 @@ a program that runs for a fixed time, you may want to set the duration to match or exceed the expected runtime. -Thread Selection +Thread selection ---------------- Python programs often use multiple threads, whether explicitly through the @@ -219,7 +219,7 @@ This option is particularly useful when investigating concurrency issues or when work is distributed across a thread pool. -Special Frames +Special frames -------------- The profiler can inject artificial frames into the captured stacks to provide @@ -249,7 +249,7 @@ see substantial time in ```` frames, consider investigating object allocation rates or using object pooling. -Real-Time Statistics +Real-time statistics -------------------- The ``--realtime-stats`` option displays sampling rate statistics during @@ -262,7 +262,7 @@ if the profiler cannot keep up. The statistics help verify that profiling is working correctly and that sufficient samples are being collected. -Profiling Modes +Profiling modes =============== The sampling profiler supports three modes that control which samples are @@ -270,7 +270,7 @@ recorded. The mode determines what the profile measures: total elapsed time, CPU execution time, or time spent holding the Global Interpreter Lock. -Wall-Clock Mode +Wall-clock mode --------------- Wall-clock mode (``--mode=wall``) captures all samples regardless of what the @@ -290,7 +290,7 @@ function. This is often exactly what you want when optimizing end-to-end latency. -CPU Mode +CPU mode -------- CPU mode (``--mode=cpu``) records samples only when the thread is actually @@ -308,7 +308,7 @@ and network calls, CPU mode reveals which computational sections are most expensive. -GIL Mode +GIL mode -------- GIL mode (``--mode=gil``) records samples only when the thread holds Python's @@ -327,7 +327,7 @@ single-threaded programs or for code that releases the GIL (such as many NumPy operations or I/O calls). -Output Formats +Output formats ============== The profiler produces output in several formats, each suited to different @@ -335,7 +335,7 @@ analysis workflows. The format is selected with a command-line flag, and output goes to stdout, a file, or a directory depending on the format. -pstats Format +pstats format ------------- The pstats format (``--pstats``) produces a text table similar to what @@ -390,7 +390,7 @@ The ``--no-summary`` option suppresses the header summary that precedes the statistics table. -Collapsed Stacks Format +Collapsed stacks format ----------------------- Collapsed stacks format (``--collapsed``) produces one line per unique call @@ -418,7 +418,7 @@ The resulting SVG can be viewed in any web browser and provides an interactive visualization where you can click to zoom into specific call paths. -Flame Graph Format +Flame graph format ------------------ Flame graph format (``--flamegraph``) produces a self-contained HTML file with @@ -452,7 +452,7 @@ at the top indicate functions that consume significant time either directly or through their callees. -Gecko Format +Gecko format ------------ Gecko format (``--gecko``) produces JSON output compatible with the Firefox @@ -486,7 +486,7 @@ For this reason, the ``--mode`` option is not available with Gecko format; all relevant data is captured automatically. -Heatmap Format +Heatmap format -------------- Heatmap format (``--heatmap``) generates an interactive HTML visualization @@ -527,7 +527,7 @@ intuitive view that shows exactly where time is spent without requiring interpretation of hierarchical visualizations. -Live Mode +Live mode ========= Live mode (``--live``) provides a terminal-based real-time view of profiling @@ -584,7 +584,7 @@ Live mode is incompatible with output format options (``--collapsed``, interface rather than producing file output. -Async-Aware Profiling +Async-aware profiling ===================== For programs using :mod:`asyncio`, the profiler offers async-aware mode @@ -623,7 +623,7 @@ Command Line Reference The complete command-line interface for reference. -Global Options +Global options -------------- .. option:: run @@ -635,7 +635,7 @@ Global Options Attach to and profile a running process by PID. -Sampling Options +Sampling options ---------------- .. option:: -i , --interval @@ -667,7 +667,7 @@ Sampling Options Enable async-aware profiling for asyncio programs. -Mode Options +Mode options ------------ .. option:: --mode @@ -681,7 +681,7 @@ Mode Options Requires ``--async-aware``. -Output Options +Output options -------------- .. option:: --pstats @@ -712,7 +712,7 @@ Output Options named ``heatmap_PID``. -pstats Display Options +pstats display options ---------------------- These options apply only to pstats format output. @@ -731,7 +731,7 @@ These options apply only to pstats format output. Omit the Legend and Summary of Interesting Functions sections from output. -Run Command Options +Run command options ------------------- .. option:: -m, --module diff --git a/Doc/library/profiling-tracing.rst b/Doc/library/profiling-tracing.rst index 0e7f3714f70a9d..60b0ef14c85da7 100644 --- a/Doc/library/profiling-tracing.rst +++ b/Doc/library/profiling-tracing.rst @@ -1,7 +1,7 @@ .. _profiling-tracing: **************************************************** -:mod:`profiling.tracing` --- Deterministic Profiler +:mod:`profiling.tracing` --- Deterministic profiler **************************************************** .. module:: profiling.tracing @@ -38,7 +38,7 @@ testing scenarios. cProfile.run('my_function()') -What Is Deterministic Profiling? +What is deterministic profiling? ================================ :dfn:`Deterministic profiling` captures every function call, function return, @@ -74,7 +74,7 @@ allows direct comparison of recursive and iterative implementations. .. _profiling-tracing-cli: -Command Line Interface +Command-line interface ====================== .. program:: profiling.tracing @@ -111,14 +111,14 @@ results to standard output (or saves them to a file). The ``-m`` option for :mod:`profile`. -Programmatic Usage Examples +Programmatic usage examples =========================== For more control over profiling, use the module's functions and classes directly. -Basic Profiling +Basic profiling --------------- The simplest approach uses the :func:`run` function:: @@ -162,7 +162,7 @@ The :class:`Profile` class also works as a context manager:: pr.print_stats() -Module Reference +Module reference ================ .. currentmodule:: profiling.tracing @@ -264,7 +264,7 @@ Module Reference profiling, no results will be available. -Using a Custom Timer +Using a custom timer ==================== The :class:`Profile` class accepts a custom timing function, allowing you to diff --git a/Doc/library/profiling.rst b/Doc/library/profiling.rst index b6d28969492259..245cb93722425d 100644 --- a/Doc/library/profiling.rst +++ b/Doc/library/profiling.rst @@ -3,7 +3,7 @@ .. _profiling-module: *************************************** -:mod:`profiling` --- Python Profilers +:mod:`profiling` --- Python profilers *************************************** .. module:: profiling @@ -22,7 +22,7 @@ single: profiling, deterministic -Introduction to Profiling +Introduction to profiling ========================= A :dfn:`profile` is a set of statistics that describes how often and for how @@ -58,7 +58,7 @@ profiling methodology: .. _choosing-a-profiler: -Choosing a Profiler +Choosing a profiler =================== For most performance analysis, use the statistical profiler @@ -74,7 +74,7 @@ complete between sampling intervals. The tradeoff is higher overhead. The following table summarizes the key differences: +--------------------+------------------------------+------------------------------+ -| Feature | Statistical Sampling | Deterministic | +| Feature | Statistical sampling | Deterministic | | | (:mod:`profiling.sampling`) | (:mod:`profiling.tracing`) | +====================+==============================+==============================+ | **Overhead** | Virtually none | Moderate | @@ -92,7 +92,7 @@ The following table summarizes the key differences: +--------------------+------------------------------+------------------------------+ -When to Use Statistical Sampling +When to use statistical sampling -------------------------------- The statistical profiler (:mod:`profiling.sampling`) is recommended for most @@ -119,7 +119,7 @@ the ``attach`` command connects to any running Python process by PID without requiring a restart or code changes. -When to Use Deterministic Tracing +When to use deterministic tracing --------------------------------- The deterministic profiler (:mod:`profiling.tracing`) instruments every function @@ -139,14 +139,14 @@ samples, but deterministic tracing records every invocation regardless of duration. -Quick Start +Quick start =========== This section provides the minimal steps needed to start profiling. For complete documentation, see the dedicated pages for each profiler. -Statistical Profiling +Statistical profiling --------------------- To profile a script, use the :mod:`profiling.sampling` module with the ``run`` @@ -171,7 +171,7 @@ duration (in seconds):: python -m profiling.sampling run -i 50 -d 30 script.py -Deterministic Profiling +Deterministic profiling ----------------------- To profile a script from the command line:: @@ -191,7 +191,7 @@ exact function call counts and timing. .. _profile-output: -Understanding Profile Output +Understanding profile output ============================ Both profilers collect function-level statistics, though they present them in @@ -230,7 +230,7 @@ Key profiling concepts: :meth:`~pstats.Stats.print_callees` methods. -Legacy Compatibility +Legacy compatibility ==================== For backward compatibility, the ``cProfile`` module remains available as an diff --git a/Doc/library/pstats.rst b/Doc/library/pstats.rst index f0c6a657c548aa..26fe3e0792b098 100644 --- a/Doc/library/pstats.rst +++ b/Doc/library/pstats.rst @@ -1,7 +1,7 @@ .. _pstats-module: ******************************************** -:mod:`pstats` --- Statistics for Profilers +:mod:`pstats` --- Statistics for profilers ******************************************** .. module:: pstats @@ -17,7 +17,7 @@ output from both :mod:`profiling.tracing` (deterministic profiler) and :mod:`profiling.sampling` (statistical profiler). -Reading and Displaying Profile Data +Reading and displaying profile data =================================== The :class:`Stats` class is the primary interface for working with profile @@ -41,7 +41,7 @@ cumulative time:: p.sort_stats(SortKey.CUMULATIVE).print_stats(10) -Working with Statistics +Working with statistics ----------------------- The :class:`Stats` class supports method chaining, making it convenient to @@ -68,7 +68,7 @@ Different sort keys highlight different aspects of performance:: p.sort_stats(SortKey.NAME).print_stats() -Filtering Output +Filtering output ---------------- The :meth:`~Stats.print_stats` method accepts restrictions that filter @@ -93,7 +93,7 @@ Combine restrictions (they apply sequentially):: p.sort_stats(SortKey.FILENAME).print_stats('foo:', .5) -Analyzing Call Relationships +Analyzing call relationships ---------------------------- The :meth:`~Stats.print_callers` method shows which functions called each @@ -109,7 +109,7 @@ listing which functions each displayed function called:: Both methods accept the same restriction arguments as :meth:`~Stats.print_stats`. -Combining Multiple Profiles +Combining multiple profiles --------------------------- Statistics from multiple profiling runs can be combined into a single @@ -336,7 +336,7 @@ The :class:`Stats` Class Sort by internal time (time in function excluding subcalls). -Command Line Interface +Command-line interface ====================== The :mod:`pstats` module can be invoked as a script to interactively browse From fe20293ce47586e0ebc0e60bcfd28abebd432bc6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:32:36 +0200 Subject: [PATCH 03/15] Links in headers don't always work nicely --- Doc/library/profile.rst | 8 ++++---- Doc/library/pstats.rst | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index b48658bc0f290e..218aa88bc49d47 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -54,8 +54,8 @@ a straightforward migration path. continue to work without modification. -:mod:`!profile` and :mod:`profiling.tracing` Module Reference -============================================================= +:mod:`!profile` and :mod:`!profiling.tracing` module reference +============================================================== Both the :mod:`profile` and :mod:`profiling.tracing` modules provide the following functions: @@ -175,8 +175,8 @@ during the called command/function execution) no profiling results will be printed. -Differences from :mod:`profiling.tracing` -========================================= +Differences from :mod:`!profiling.tracing` +========================================== The :mod:`profile` module differs from :mod:`profiling.tracing` in several ways: diff --git a/Doc/library/pstats.rst b/Doc/library/pstats.rst index 26fe3e0792b098..c00e56ffc3332e 100644 --- a/Doc/library/pstats.rst +++ b/Doc/library/pstats.rst @@ -127,8 +127,8 @@ When files are combined, statistics for identical functions (same file, line, and name) are accumulated, giving an aggregate view across all profiling runs. -The :class:`Stats` Class -======================== +The :class:`!Stats` class +========================= .. class:: Stats(*filenames_or_profile, stream=sys.stdout) From 87ae061da2fb66e5fb74615dbee65aa21994ce0c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:34:08 +0200 Subject: [PATCH 04/15] Global Interpreter Lock -> global interpreter lock --- Doc/library/profiling-sampling.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/profiling-sampling.rst b/Doc/library/profiling-sampling.rst index 97d145f1311087..8b3910c326df4d 100644 --- a/Doc/library/profiling-sampling.rst +++ b/Doc/library/profiling-sampling.rst @@ -267,7 +267,7 @@ Profiling modes The sampling profiler supports three modes that control which samples are recorded. The mode determines what the profile measures: total elapsed time, -CPU execution time, or time spent holding the Global Interpreter Lock. +CPU execution time, or time spent holding the global interpreter lock. Wall-clock mode @@ -312,7 +312,7 @@ GIL mode -------- GIL mode (``--mode=gil``) records samples only when the thread holds Python's -Global Interpreter Lock:: +global interpreter lock:: python -m profiling.sampling run --mode=gil script.py @@ -477,7 +477,7 @@ CPU activity, enabling analysis features specific to Python's threading model. The profiler emits interval markers that appear as colored bands in the Firefox Profiler timeline: -- **GIL markers**: Show when threads hold or release the Global Interpreter Lock +- **GIL markers**: Show when threads hold or release the global interpreter lock - **CPU markers**: Show when threads are executing on CPU versus idle - **Code type markers**: Distinguish Python code from native (C extension) code - **GC markers**: Indicate garbage collection activity From 8f890d0914afa56cd8e994bd9f215319b28b8c6c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:40:07 +0200 Subject: [PATCH 05/15] No need for caps --- Doc/library/profiling-sampling.rst | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Doc/library/profiling-sampling.rst b/Doc/library/profiling-sampling.rst index 8b3910c326df4d..9b7b1c1f1477df 100644 --- a/Doc/library/profiling-sampling.rst +++ b/Doc/library/profiling-sampling.rst @@ -359,17 +359,17 @@ anywhere on the stack). The percentages and times derive from these counts and the total profiling duration. Time units are selected automatically based on the data: seconds, milliseconds, or microseconds. -The output includes a Legend explaining each column and a Summary of -Interesting Functions section that highlights: +The output includes a legend explaining each column and a summary of +interesting functions that highlights: -- **Hot Spots**: Functions with high direct/cumulative sample ratio (time spent +- **Hot spots**: functions with high direct/cumulative sample ratio (time spent directly executing rather than waiting for callees) -- **Indirect Calls**: Functions appearing frequently on the stack via other +- **Indirect calls**: functions appearing frequently on the stack via other callers -- **Call Magnification**: Functions where cumulative samples far exceed direct +- **Call magnification**: functions where cumulative samples far exceed direct samples, indicating significant time in nested calls -Use ``--no-summary`` to suppress both the Legend and Summary sections. +Use ``--no-summary`` to suppress both the legend and summary sections. To save pstats output to a file instead of stdout:: @@ -477,10 +477,10 @@ CPU activity, enabling analysis features specific to Python's threading model. The profiler emits interval markers that appear as colored bands in the Firefox Profiler timeline: -- **GIL markers**: Show when threads hold or release the global interpreter lock -- **CPU markers**: Show when threads are executing on CPU versus idle -- **Code type markers**: Distinguish Python code from native (C extension) code -- **GC markers**: Indicate garbage collection activity +- **GIL markers**: show when threads hold or release the global interpreter lock +- **CPU markers**: show when threads are executing on CPU versus idle +- **Code type markers**: distinguish Python code from native (C extension) code +- **GC markers**: indicate garbage collection activity For this reason, the ``--mode`` option is not available with Gecko format; all relevant data is captured automatically. @@ -507,17 +507,17 @@ responsible for time consumption. The heatmap interface provides several interactive features: -- **Coloring modes**: Toggle between "Self Time" (direct execution) and +- **Coloring modes**: toggle between "Self Time" (direct execution) and "Total Time" (cumulative, including time in called functions) -- **Cold code filtering**: Show all lines or only lines with samples -- **Call graph navigation**: Each line has buttons to navigate to callers +- **Cold code filtering**: show all lines or only lines with samples +- **Call graph navigation**: each line has buttons to navigate to callers (functions that called this line) and callees (functions called from here) -- **Scroll minimap**: A vertical overview showing the heat distribution across +- **Scroll minimap**: a vertical overview showing the heat distribution across the entire file -- **Hierarchical index**: Files organized by type (stdlib, site-packages, +- **Hierarchical index**: files organized by type (stdlib, site-packages, project) with aggregate sample counts per folder -- **Dark/light theme**: Toggle with preference saved across sessions -- **Line linking**: Click line numbers to create shareable URLs +- **Dark/light theme**: toggle with preference saved across sessions +- **Line linking**: click line numbers to create shareable URLs Heatmaps are especially useful when you know which file contains a performance issue but need to identify the specific lines. Many developers prefer this From bf389fe2ce1842dc589dd9df8b66c2b673b2d27a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:41:04 +0200 Subject: [PATCH 06/15] Exceptionally use plaintext formatting for output --- Doc/library/profiling-sampling.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/profiling-sampling.rst b/Doc/library/profiling-sampling.rst index 9b7b1c1f1477df..e24550396340b0 100644 --- a/Doc/library/profiling-sampling.rst +++ b/Doc/library/profiling-sampling.rst @@ -398,7 +398,9 @@ stack, with a count of how many times that stack was sampled:: python -m profiling.sampling run --collapsed script.py -The output looks like:: +The output looks like: + +.. code-block:: text main;process_data;parse_json;decode_utf8 42 main;process_data;parse_json 156 From 7d7b14ece742f8e9dc1e2b03d84abb425777fc56 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:48:11 +0200 Subject: [PATCH 07/15] Prefer anonymous links --- Doc/library/profiling-sampling.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/profiling-sampling.rst b/Doc/library/profiling-sampling.rst index e24550396340b0..02e981a8169053 100644 --- a/Doc/library/profiling-sampling.rst +++ b/Doc/library/profiling-sampling.rst @@ -463,11 +463,11 @@ Profiler:: python -m profiling.sampling run --gecko script.py python -m profiling.sampling run --gecko -o profile.json script.py -The `Firefox Profiler `_ is a sophisticated +The `Firefox Profiler `__ is a sophisticated web-based tool originally built for profiling Firefox itself. It provides features beyond basic flame graphs, including a timeline view, call tree exploration, and marker visualization. See the -`Firefox Profiler documentation `_ for +`Firefox Profiler documentation `__ for detailed usage instructions. To use the output, open the Firefox Profiler in your browser and load the @@ -756,9 +756,9 @@ Run command options :mod:`pstats` Statistics analysis for profile data. - `Firefox Profiler `_ + `Firefox Profiler `__ Web-based profiler that accepts Gecko format output. See the - `documentation `_ for usage details. + `documentation `__ for usage details. - `FlameGraph `_ + `FlameGraph `__ Tools for generating flame graphs from collapsed stack format. From 6f92adbea9c7c5408c6301ea8a28c9d01950bdf6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:53:44 +0200 Subject: [PATCH 08/15] Use :kbd: role https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html\#role-kbd --- Doc/library/profiling-sampling.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Doc/library/profiling-sampling.rst b/Doc/library/profiling-sampling.rst index 02e981a8169053..8c6b1022eec3ef 100644 --- a/Doc/library/profiling-sampling.rst +++ b/Doc/library/profiling-sampling.rst @@ -545,40 +545,40 @@ and 24 lines tall. Within live mode, keyboard commands control the display: -``q`` +:kbd:`q` Quit the profiler and return to the shell. -``s`` / ``S`` +:kbd:`s` / :kbd:`S` Cycle through sort orders forward/backward (sample count, percentage, total time, cumulative percentage, cumulative time). -``p`` +:kbd:`p` Pause or resume display updates. Sampling continues while paused. -``r`` +:kbd:`r` Reset all statistics and start fresh. -``/`` +:kbd:`/` Enter filter mode to search for functions by name. Type a pattern and press Enter to filter, or Escape to cancel. -``c`` +:kbd:`c` Clear the current filter. -``t`` +:kbd:`t` Toggle between viewing all threads combined or per-thread statistics. -``←`` ``→`` or ``↑`` ``↓`` +:kbd:`←` :kbd:`→` or :kbd:`↑` :kbd:`↓` In per-thread view, navigate between threads. -``+`` / ``-`` +:kbd:`+` / :kbd:`-` Increase or decrease the display refresh rate (range: 0.05s to 1.0s). -``x`` +:kbd:`x` Toggle trend indicators that show whether functions are becoming hotter or cooler over time. -``h`` or ``?`` +:kbd:`h` or :kbd:`?` Show the help screen with all available commands. Live mode is incompatible with output format options (``--collapsed``, From ffd5a27b0df25759db067959b1c490ce598aca0a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:55:10 +0200 Subject: [PATCH 09/15] Command-line interface --- Doc/library/profiling-sampling.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/profiling-sampling.rst b/Doc/library/profiling-sampling.rst index 8c6b1022eec3ef..06bab1657bed9d 100644 --- a/Doc/library/profiling-sampling.rst +++ b/Doc/library/profiling-sampling.rst @@ -617,7 +617,7 @@ profiling uses a different stack reconstruction mechanism that tracks task relationships rather than raw Python frames. -Command Line Reference +Command-line interface ====================== .. program:: profiling.sampling From 6f635e6c61a7b7a9caae458c94b05d4353067ed6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:02:40 +0200 Subject: [PATCH 10/15] Use shell-session formatting --- Doc/library/profiling-tracing.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/profiling-tracing.rst b/Doc/library/profiling-tracing.rst index 60b0ef14c85da7..d0393d7e091e2a 100644 --- a/Doc/library/profiling-tracing.rst +++ b/Doc/library/profiling-tracing.rst @@ -80,7 +80,9 @@ Command-line interface .. program:: profiling.tracing The :mod:`profiling.tracing` module can be invoked as a script to profile -another script or module:: +another script or module: + +.. code-block:: shell-session python -m profiling.tracing [-o output_file] [-s sort_order] (-m module | myscript.py) From e3ed03c1522ab07885cdceaa6ee6f616ba302f92 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:05:53 +0200 Subject: [PATCH 11/15] Fix references --- Doc/library/profiling-tracing.rst | 10 +++++----- Doc/whatsnew/3.8.rst | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/library/profiling-tracing.rst b/Doc/library/profiling-tracing.rst index d0393d7e091e2a..091544a250c3d0 100644 --- a/Doc/library/profiling-tracing.rst +++ b/Doc/library/profiling-tracing.rst @@ -123,7 +123,7 @@ directly. Basic profiling --------------- -The simplest approach uses the :func:`run` function:: +The simplest approach uses the :func:`!run` function:: import profiling.tracing profiling.tracing.run('my_function()') @@ -134,10 +134,10 @@ To save results for later analysis:: profiling.tracing.run('my_function()', 'output.prof') -Using the Profile Class ------------------------ +Using the :class:`!Profile` class +--------------------------------- -The :class:`Profile` class provides fine-grained control:: +The :class:`!Profile` class provides fine-grained control:: import profiling.tracing import pstats @@ -154,7 +154,7 @@ The :class:`Profile` class provides fine-grained control:: ps.print_stats() print(s.getvalue()) -The :class:`Profile` class also works as a context manager:: +The :class:`!Profile` class also works as a context manager:: import profiling.tracing diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index f18a408ec11e60..545a17aecab8ee 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1727,7 +1727,7 @@ Deprecated * Deprecated passing the following arguments as keyword arguments: - *func* in :func:`functools.partialmethod`, :func:`weakref.finalize`, - :meth:`profile.Profile.runcall`, :meth:`cProfile.Profile.runcall`, + :meth:`profile.Profile.runcall`, :meth:`!cProfile.Profile.runcall`, :meth:`bdb.Bdb.runcall`, :meth:`trace.Trace.runfunc` and :func:`curses.wrapper`. - *function* in :meth:`unittest.TestCase.addCleanup`. From 151e2808d10d704a8f2f5356c8a209ca2ccd8528 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:06:09 +0200 Subject: [PATCH 12/15] Wording --- Doc/library/profiling-tracing.rst | 2 +- Doc/library/profiling.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/profiling-tracing.rst b/Doc/library/profiling-tracing.rst index 091544a250c3d0..4d43ecfbb6465e 100644 --- a/Doc/library/profiling-tracing.rst +++ b/Doc/library/profiling-tracing.rst @@ -299,7 +299,7 @@ Limitations Deterministic profiling has inherent limitations related to timing accuracy. -The underlying timer typically has a resolution of about 1 millisecond. +The underlying timer typically has a resolution of about one millisecond. Measurements cannot be more accurate than this resolution. With enough measurements, timing errors tend to average out, but individual measurements may be imprecise. diff --git a/Doc/library/profiling.rst b/Doc/library/profiling.rst index 245cb93722425d..c2a5ab5b155555 100644 --- a/Doc/library/profiling.rst +++ b/Doc/library/profiling.rst @@ -38,7 +38,7 @@ profiling methodology: :mod:`profiling.sampling` A statistical profiler that periodically samples the call stack. Run scripts directly or attach to running processes by PID. Provides multiple output - formats (flamegraphs, heatmaps, Firefox Profiler), GIL analysis, GC tracking, + formats (flame graphs, heatmaps, Firefox Profiler), GIL analysis, GC tracking, and multiple profiling modes (wall-clock, CPU, GIL) with virtually no overhead. :mod:`profiling.tracing` @@ -176,7 +176,7 @@ Deterministic profiling To profile a script from the command line:: - python -m profiling.tracing myscript.py + python -m profiling.tracing script.py To profile a piece of code programmatically: @@ -221,7 +221,7 @@ Key profiling concepts: 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 ``total/primitive`` (for example, ``3/1`` - means 3 total calls, 1 primitive). + means three total calls, one primitive). **Caller/Callee relationships** Which functions called a given function (callers) and which functions it From c20aa923daa337ae21c9dc3c47f7dc6adf426e57 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:27:06 +0200 Subject: [PATCH 13/15] Link to pstats CLI --- Doc/library/cmdline.rst | 2 +- Doc/library/pstats.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/cmdline.rst b/Doc/library/cmdline.rst index 7bc2b93b3c2851..6418706269f1ed 100644 --- a/Doc/library/cmdline.rst +++ b/Doc/library/cmdline.rst @@ -33,7 +33,7 @@ The following modules have a command-line interface. * :mod:`poplib` * :ref:`profiling.sampling ` * :ref:`profiling.tracing ` -* :mod:`pstats` +* :ref:`pstats ` * :ref:`py_compile ` * :mod:`pyclbr` * :mod:`pydoc` diff --git a/Doc/library/pstats.rst b/Doc/library/pstats.rst index c00e56ffc3332e..b2310a49dea9e3 100644 --- a/Doc/library/pstats.rst +++ b/Doc/library/pstats.rst @@ -336,6 +336,8 @@ The :class:`!Stats` class Sort by internal time (time in function excluding subcalls). +.. _pstats-cli: + Command-line interface ====================== From 0ae0b99cf1819efe47182c3cd8b7f76bdfaa837c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:33:50 +0200 Subject: [PATCH 14/15] Code formatting --- Doc/library/pstats.rst | 62 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/Doc/library/pstats.rst b/Doc/library/pstats.rst index b2310a49dea9e3..ce1cc5c9535ca6 100644 --- a/Doc/library/pstats.rst +++ b/Doc/library/pstats.rst @@ -186,37 +186,37 @@ The :class:`!Stats` class Valid sort keys: - +------------------+---------------------+----------------------+ - | String | Enum | Meaning | - +==================+=====================+======================+ - | ``'calls'`` | SortKey.CALLS | call count | - +------------------+---------------------+----------------------+ - | ``'cumulative'`` | SortKey.CUMULATIVE | cumulative time | - +------------------+---------------------+----------------------+ - | ``'cumtime'`` | N/A | cumulative time | - +------------------+---------------------+----------------------+ - | ``'file'`` | N/A | file name | - +------------------+---------------------+----------------------+ - | ``'filename'`` | SortKey.FILENAME | file name | - +------------------+---------------------+----------------------+ - | ``'module'`` | N/A | file name | - +------------------+---------------------+----------------------+ - | ``'ncalls'`` | N/A | call count | - +------------------+---------------------+----------------------+ - | ``'pcalls'`` | SortKey.PCALLS | primitive call count | - +------------------+---------------------+----------------------+ - | ``'line'`` | SortKey.LINE | line number | - +------------------+---------------------+----------------------+ - | ``'name'`` | SortKey.NAME | function name | - +------------------+---------------------+----------------------+ - | ``'nfl'`` | SortKey.NFL | name/file/line | - +------------------+---------------------+----------------------+ - | ``'stdname'`` | SortKey.STDNAME | standard name | - +------------------+---------------------+----------------------+ - | ``'time'`` | SortKey.TIME | internal time | - +------------------+---------------------+----------------------+ - | ``'tottime'`` | N/A | internal time | - +------------------+---------------------+----------------------+ + +------------------+------------------------+----------------------+ + | String | Enum | Meaning | + +==================+========================+======================+ + | ``'calls'`` | ``SortKey.CALLS`` | call count | + +------------------+------------------------+----------------------+ + | ``'cumulative'`` | ``SortKey.CUMULATIVE`` | cumulative time | + +------------------+------------------------+----------------------+ + | ``'cumtime'`` | N/A | cumulative time | + +------------------+------------------------+----------------------+ + | ``'file'`` | N/A | file name | + +------------------+------------------------+----------------------+ + | ``'filename'`` | ``SortKey.FILENAME`` | file name | + +------------------+------------------------+----------------------+ + | ``'module'`` | N/A | file name | + +------------------+------------------------+----------------------+ + | ``'ncalls'`` | N/A | call count | + +------------------+------------------------+----------------------+ + | ``'pcalls'`` | ``SortKey.PCALLS`` | primitive call count | + +------------------+------------------------+----------------------+ + | ``'line'`` | ``SortKey.LINE`` | line number | + +------------------+------------------------+----------------------+ + | ``'name'`` | ``SortKey.NAME`` | function name | + +------------------+------------------------+----------------------+ + | ``'nfl'`` | ``SortKey.NFL`` | name/file/line | + +------------------+------------------------+----------------------+ + | ``'stdname'`` | ``SortKey.STDNAME`` | standard name | + +------------------+------------------------+----------------------+ + | ``'time'`` | ``SortKey.TIME`` | internal time | + +------------------+------------------------+----------------------+ + | ``'tottime'`` | N/A | internal time | + +------------------+------------------------+----------------------+ All sorts on statistics are in descending order (most time consuming first), while name, file, and line number sorts are ascending From e39ed6977e6d69353d8a9b5f34288443dc07aa77 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:35:52 +0200 Subject: [PATCH 15/15] Link Tachyon from release highlights --- Doc/whatsnew/3.15.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 6fc31a10d5bcab..c345c14fd1c647 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -67,6 +67,8 @@ Summary -- Release highlights * :pep:`799`: :ref:`A dedicated profiling package for organizing Python profiling tools ` +* :pep:`799`: :ref:`Tachyon: High frequency statistical sampling profiler + profiling tools ` * :pep:`686`: :ref:`Python now uses UTF-8 as the default encoding ` * :pep:`782`: :ref:`A new PyBytesWriter C API to create a Python bytes object