Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add code examples to the profiling.sampling ddocs
  • Loading branch information
pablogsal committed Dec 12, 2025
commit e74ce95dafe0d9f6a8c7096c524e77b6bd1ff2b2
66 changes: 66 additions & 0 deletions Doc/library/profiling.sampling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ production systems. The target process requires no modification and need not
be restarted. The profiler attaches, collects samples for the specified
duration, then detaches and produces output.

::

python -m profiling.sampling attach --live 12345
python -m profiling.sampling attach --flamegraph -d 30 -o profile.html 12345

On most systems, attaching to another process requires appropriate permissions.
See :ref:`profiling-permissions` for platform-specific requirements.

Expand Down Expand Up @@ -529,6 +534,25 @@ I/O-bound or waiting. The function spends most of its time waiting for network,
disk, locks, or sleep. CPU optimization won't help here; consider async I/O,
connection pooling, or reducing wait time instead.

.. code-block:: python
import time
def do_sleep():
time.sleep(2)
def do_compute():
sum(i**2 for i in range(1000000))
if __name__ == "__main__":
do_sleep()
do_compute()
::

python -m profiling.sampling run --mode=wall script.py # do_sleep ~98%, do_compute ~1%
python -m profiling.sampling run --mode=cpu script.py # do_sleep absent, do_compute dominates


GIL mode
--------
Expand All @@ -553,6 +577,29 @@ GIL?" and "why are my other threads starving?" It can also be useful in
single-threaded programs to distinguish Python execution time from time spent
in C extensions or I/O.

.. code-block:: python
import hashlib
def hash_work():
# C extension - releases GIL during computation
for _ in range(200):
hashlib.sha256(b"data" * 250000).hexdigest()
def python_work():
# Pure Python - holds GIL during computation
for _ in range(3):
sum(i**2 for i in range(1000000))
if __name__ == "__main__":
hash_work()
python_work()
::

python -m profiling.sampling run --mode=cpu script.py # hash_work ~42%, python_work ~38%
python -m profiling.sampling run --mode=gil script.py # hash_work ~5%, python_work ~60%


Exception mode
--------------
Expand Down Expand Up @@ -952,6 +999,25 @@ stack often shows event loop internals rather than the logical flow of your
coroutines. Async-aware mode addresses this by tracking which task is running
and presenting stacks that reflect the ``await`` chain.

.. code-block:: python
import asyncio
async def fetch(url):
await asyncio.sleep(0.1)
return url
async def main():
for _ in range(50):
await asyncio.gather(fetch("a"), fetch("b"), fetch("c"))
if __name__ == "__main__":
asyncio.run(main())
::

python -m profiling.sampling run --async-aware --flamegraph -o out.html script.py

.. note::

Async-aware profiling requires the target process to have the :mod:`asyncio`
Expand Down
Loading