Skip to content

Commit beef4fc

Browse files
committed
📝 Update performance measurements section
* Add tprof
1 parent eefba94 commit beef4fc

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

docs/performance/index.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,19 @@ Performance measurements
6464
Once you have worked with your code, it can be useful to examine its efficiency
6565
more closely. `cProfile
6666
<https://docs.python.org/3.14/library/profile.html#module-cProfile>`_,
67-
:doc:`ipython-profiler` or :doc:`scalene` can be used for this.
67+
:doc:`ipython-profiler`, :doc:`scalene` or :doc:`tprof` can be used for this. So
68+
far, I usually carry out the following steps:
69+
70+
#. I profile the entire programme with `cProfile
71+
<https://docs.python.org/3.14/library/profile.html#module-cProfile>`__ or
72+
`py-spy <https://github.com/benfred/py-spy>`_ to find slow functions.
73+
#. Then I optimise a slow function.
74+
#. Finally, I create a new profile and filter out the result of my optimised
75+
version so that I can compare the results.
76+
77+
:mod:`sys.monitoring` in Python 3.12 simplified the monitoring of certain
78+
functions. :doc:`tprof` uses this, so that in the last step, only the profile
79+
for the optimised function needs to be created.
6880

6981
.. versionadded:: Python3.15
7082
:pep:`799` will provide a special profiling module that organises the
@@ -93,6 +105,7 @@ more closely. `cProfile
93105

94106
ipython-profiler.ipynb
95107
scalene.ipynb
108+
tprof
96109
tachyon
97110

98111
Search for existing implementations

docs/performance/tprof.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
.. SPDX-FileCopyrightText: 2026 Veit Schiele
2+
..
3+
.. SPDX-License-Identifier: BSD-3-Clause
4+
5+
``tprof``
6+
=========
7+
8+
`tprof <https://github.com/adamchainz/tprof>`_ measures the time spent executing
9+
a module in specific functions. Unlike other profilers, it only tracks the
10+
specified functions with :mod:`sys.monitoring`, eliminating the need for
11+
filtering.
12+
13+
``tprof`` supports use as a command line programme and with a Python interface:
14+
15+
:samp:`uv run tprof -t {MODULE}:{FUNCTION} (-m {MODULE} | {PATH/TO/SCRIPT})`
16+
Suppose you have determined that creating :class:`pathlib.Path` objects in
17+
the :mod:`main` module is slowing down your code. Here’s how you can measure
18+
this with ``tprof``:
19+
20+
.. code-block:: console
21+
22+
$ uv run tprof -t pathlib:Path.open -m main
23+
🎯 tprof results:
24+
function calls total mean ± σ min … max
25+
pathlib:Path.open() 1 93μs 93μs 93μs … 93μs
26+
27+
With the ``-x`` option, you can also compare two functions with each other:
28+
29+
.. code-block:: console
30+
31+
$ uv run tprof -x -t old -m main -t new -m main
32+
🎯 tprof results:
33+
function calls total mean ± σ min … max delta
34+
main:old() 1 41μs 41μs 41μs … 41μs -
35+
main:new() 1 20μs 20μs 20μs … 20μs -50.67%
36+
37+
``tprof(*targets, label: str | None = None, compare: bool = False)``
38+
uses this code as a :doc:`context manager
39+
<python-basics:control-flow/with>`_ or :doc:`decorator
40+
<python-basics:functions/decorators>`_ in your code to perform profiling in
41+
a specific block. The report is generated each time the block is run
42+
through.
43+
44+
``*targets``
45+
are callable elements for profiling or references to elements that are
46+
resolved with :func:`pkgutil.resolve_name`.
47+
``label``
48+
is an optional string that can be added to the report as a header.
49+
``compare``
50+
set to ``True`` activates comparison mode.
51+
52+
Example:
53+
54+
.. code-block:: Python
55+
56+
from pathlib import Path
57+
58+
from tprof import tprof
59+
60+
with tprof(Path.open):
61+
p = Path("docs", "save-data", "myfile.txt")
62+
f = p.open()
63+
64+
.. code-block:: console
65+
66+
$ uv run python main.py
67+
🎯 tprof results:
68+
function calls total mean ± σ min … max
69+
pathlib:Path.open() 1 82μs 82μs 82μs … 82μs

0 commit comments

Comments
 (0)