From c84bc363aab1df3ac5787c24e3bdfeabfde5d831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Sun, 8 Feb 2026 20:47:39 +0100 Subject: [PATCH] bpo-18795: Add cumpercall and totalpercall keys to pstats sort_stats Co-authored-by: Alexandre Dias --- Doc/library/pstats.rst | 69 ++++++++++--------- Lib/pstats.py | 42 +++++++---- Lib/test/test_pstats.py | 2 +- .../2022-03-16-00-18-52.bpo-18795.ov0vob.rst | 1 + 4 files changed, 67 insertions(+), 47 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-03-16-00-18-52.bpo-18795.ov0vob.rst diff --git a/Doc/library/pstats.rst b/Doc/library/pstats.rst index ce1cc5c9535ca6..7b8138672c8471 100644 --- a/Doc/library/pstats.rst +++ b/Doc/library/pstats.rst @@ -186,37 +186,41 @@ 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 | + +--------------------+------------------------+--------------------------+ + | ``'cumpercall'`` | N/A | cumulative time per call | + +--------------------+------------------------+--------------------------+ + | ``'totalpercall'`` | N/A | total time per call | + +--------------------+------------------------+--------------------------+ All sorts on statistics are in descending order (most time consuming first), while name, file, and line number sorts are ascending @@ -234,6 +238,9 @@ The :class:`!Stats` class .. versionadded:: 3.7 The :class:`SortKey` enum. + .. versionadded:: 3.15 + Added the ``cumpercall`` and ``totalpercall`` keys. + .. method:: reverse_order() Reverse the current sort order. diff --git a/Lib/pstats.py b/Lib/pstats.py index 07ecda07796e44..8a55aed4352458 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -204,19 +204,21 @@ def dump_stats(self, filename): # list the tuple indices and directions for sorting, # along with some printable description sort_arg_dict_default = { - "calls" : (((1,-1), ), "call count"), - "ncalls" : (((1,-1), ), "call count"), - "cumtime" : (((3,-1), ), "cumulative time"), - "cumulative": (((3,-1), ), "cumulative time"), - "filename" : (((4, 1), ), "file name"), - "line" : (((5, 1), ), "line number"), - "module" : (((4, 1), ), "file name"), - "name" : (((6, 1), ), "function name"), - "nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"), - "pcalls" : (((0,-1), ), "primitive call count"), - "stdname" : (((7, 1), ), "standard name"), - "time" : (((2,-1), ), "internal time"), - "tottime" : (((2,-1), ), "internal time"), + "calls" : (((1,-1), ), "call count"), + "ncalls" : (((1,-1), ), "call count"), + "cumtime" : (((4,-1), ), "cumulative time"), + "cumulative" : (((4,-1), ), "cumulative time"), + "filename" : (((6, 1), ), "file name"), + "line" : (((7, 1), ), "line number"), + "module" : (((6, 1), ), "file name"), + "name" : (((8, 1), ), "function name"), + "nfl" : (((8, 1),(6, 1),(7, 1),), "name/file/line"), + "pcalls" : (((0,-1), ), "primitive call count"), + "stdname" : (((9, 1), ), "standard name"), + "time" : (((2,-1), ), "internal time"), + "tottime" : (((2,-1), ), "internal time"), + "cumpercall" : (((5,-1), ), "cumulative time per call"), + "totalpercall": (((3,-1), ), "total time per call"), } def get_sort_arg_defs(self): @@ -265,8 +267,18 @@ def sort_stats(self, *field): stats_list = [] for func, (cc, nc, tt, ct, callers) in self.stats.items(): - stats_list.append((cc, nc, tt, ct) + func + - (func_std_string(func), func)) + if nc == 0: + npc = 0 + else: + npc = float(tt)/nc + + if cc == 0: + cpc = 0 + else: + cpc = float(ct)/cc + + stats_list.append((cc, nc, tt, npc, ct, cpc) + func + + (func_std_string(func), func)) stats_list.sort(key=cmp_to_key(TupleComp(sort_tuple).compare)) diff --git a/Lib/test/test_pstats.py b/Lib/test/test_pstats.py index a26a8c1d522a70..dabcb84b6d1103 100644 --- a/Lib/test/test_pstats.py +++ b/Lib/test/test_pstats.py @@ -85,7 +85,7 @@ def test_sort_stats_int(self): def test_sort_stats_string(self): for sort_name in ['calls', 'ncalls', 'cumtime', 'cumulative', 'filename', 'line', 'module', 'name', 'nfl', 'pcalls', - 'stdname', 'time', 'tottime']: + 'stdname', 'time', 'tottime', 'cumpercall', 'totalpercall']: self.stats.sort_stats(sort_name) self.assertEqual(self.stats.sort_type, self.stats.sort_arg_dict_default[sort_name][-1]) diff --git a/Misc/NEWS.d/next/Library/2022-03-16-00-18-52.bpo-18795.ov0vob.rst b/Misc/NEWS.d/next/Library/2022-03-16-00-18-52.bpo-18795.ov0vob.rst new file mode 100644 index 00000000000000..0fcb7f1e386319 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-16-00-18-52.bpo-18795.ov0vob.rst @@ -0,0 +1 @@ +Added ``cumpercall`` and ``totalpercall`` keys to pstats sort_stats