Skip to content

Commit 519bee4

Browse files
authored
gh-138122: Add code examples to the profiling.sampling ddocs (#142609)
1 parent 3b38388 commit 519bee4

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

Doc/library/profiling.sampling.rst

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ production systems. The target process requires no modification and need not
191191
be restarted. The profiler attaches, collects samples for the specified
192192
duration, then detaches and produces output.
193193

194+
::
195+
196+
python -m profiling.sampling attach --live 12345
197+
python -m profiling.sampling attach --flamegraph -d 30 -o profile.html 12345
198+
194199
On most systems, attaching to another process requires appropriate permissions.
195200
See :ref:`profiling-permissions` for platform-specific requirements.
196201

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

537+
.. code-block:: python
538+
539+
import time
540+
541+
def do_sleep():
542+
time.sleep(2)
543+
544+
def do_compute():
545+
sum(i**2 for i in range(1000000))
546+
547+
if __name__ == "__main__":
548+
do_sleep()
549+
do_compute()
550+
551+
::
552+
553+
python -m profiling.sampling run --mode=wall script.py # do_sleep ~98%, do_compute ~1%
554+
python -m profiling.sampling run --mode=cpu script.py # do_sleep absent, do_compute dominates
555+
532556

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

580+
.. code-block:: python
581+
582+
import hashlib
583+
584+
def hash_work():
585+
# C extension - releases GIL during computation
586+
for _ in range(200):
587+
hashlib.sha256(b"data" * 250000).hexdigest()
588+
589+
def python_work():
590+
# Pure Python - holds GIL during computation
591+
for _ in range(3):
592+
sum(i**2 for i in range(1000000))
593+
594+
if __name__ == "__main__":
595+
hash_work()
596+
python_work()
597+
598+
::
599+
600+
python -m profiling.sampling run --mode=cpu script.py # hash_work ~42%, python_work ~38%
601+
python -m profiling.sampling run --mode=gil script.py # hash_work ~5%, python_work ~60%
602+
556603

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

1002+
.. code-block:: python
1003+
1004+
import asyncio
1005+
1006+
async def fetch(url):
1007+
await asyncio.sleep(0.1)
1008+
return url
1009+
1010+
async def main():
1011+
for _ in range(50):
1012+
await asyncio.gather(fetch("a"), fetch("b"), fetch("c"))
1013+
1014+
if __name__ == "__main__":
1015+
asyncio.run(main())
1016+
1017+
::
1018+
1019+
python -m profiling.sampling run --async-aware --flamegraph -o out.html script.py
1020+
9551021
.. note::
9561022

9571023
Async-aware profiling requires the target process to have the :mod:`asyncio`
18.8 KB
Loading

0 commit comments

Comments
 (0)