Skip to content

Commit ae1120a

Browse files
committed
better cProfile CLI defaults: sort by time, restrict to top 20
adds option -n to restrict to top n lines (defaults to 20 for CLI) set default of -s to sort by time (instead of unsorted) "python3 -m cProfile foo.py" directly usable.
1 parent c664b34 commit ae1120a

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

Lib/cProfile.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
# Simple interface
1414

1515
def run(statement, filename=None, sort=-1):
16-
return _pyprofile._Utils(Profile).run(statement, filename, sort)
16+
return _pyprofile._Utils(Profile).run(statement, filename, sort,
17+
numresults)
1718

18-
def runctx(statement, globals, locals, filename=None, sort=-1):
19+
def runctx(statement, globals, locals, filename=None, sort=-1,
20+
numresults=None):
1921
return _pyprofile._Utils(Profile).runctx(statement, globals, locals,
20-
filename, sort)
22+
filename, sort, numresults)
2123

2224
run.__doc__ = _pyprofile.run.__doc__
2325
runctx.__doc__ = _pyprofile.runctx.__doc__
@@ -37,9 +39,10 @@ class Profile(_lsprof.Profiler):
3739
# Most of the functionality is in the base class.
3840
# This subclass only adds convenient and backward-compatible methods.
3941

40-
def print_stats(self, sort=-1):
42+
def print_stats(self, sort=-1, numresults=None):
4143
import pstats
42-
pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
44+
pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats(
45+
numresults)
4346

4447
def dump_stats(self, file):
4548
import marshal
@@ -155,8 +158,10 @@ def main():
155158
help="Save stats to <outfile>", default=None)
156159
parser.add_option('-s', '--sort', dest="sort",
157160
help="Sort order when printing to stdout, based on pstats.Stats class",
158-
default=-1,
161+
default='time',
159162
choices=sorted(pstats.Stats.sort_arg_dict_default))
163+
parser.add_option('-n', '--numresults', dest="numresults", type="int",
164+
help="Number of results to show", default=20)
160165
parser.add_option('-m', dest="module", action="store_true",
161166
help="Profile a library module", default=False)
162167

@@ -185,7 +190,8 @@ def main():
185190
'__package__': None,
186191
'__cached__': None,
187192
}
188-
runctx(code, globs, None, options.outfile, options.sort)
193+
runctx(code, globs, None, options.outfile, options.sort,
194+
options.numresults)
189195
else:
190196
parser.print_usage()
191197
return parser

Lib/profile.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,37 +47,37 @@ class _Utils:
4747
def __init__(self, profiler):
4848
self.profiler = profiler
4949

50-
def run(self, statement, filename, sort):
50+
def run(self, statement, filename, sort, numresults):
5151
prof = self.profiler()
5252
try:
5353
prof.run(statement)
5454
except SystemExit:
5555
pass
5656
finally:
57-
self._show(prof, filename, sort)
57+
self._show(prof, filename, sort, numresults)
5858

59-
def runctx(self, statement, globals, locals, filename, sort):
59+
def runctx(self, statement, globals, locals, filename, sort, numresults):
6060
prof = self.profiler()
6161
try:
6262
prof.runctx(statement, globals, locals)
6363
except SystemExit:
6464
pass
6565
finally:
66-
self._show(prof, filename, sort)
66+
self._show(prof, filename, sort, numresults)
6767

68-
def _show(self, prof, filename, sort):
68+
def _show(self, prof, filename, sort, numresults):
6969
if filename is not None:
7070
prof.dump_stats(filename)
7171
else:
72-
prof.print_stats(sort)
72+
prof.print_stats(sort, numresults)
7373

7474

7575
#**************************************************************************
7676
# The following are the static member functions for the profiler class
7777
# Note that an instance of Profile() is *not* needed to call them.
7878
#**************************************************************************
7979

80-
def run(statement, filename=None, sort=-1):
80+
def run(statement, filename=None, sort=-1, numresults=None):
8181
"""Run statement under profiler optionally saving results in filename
8282
8383
This function takes a single argument that can be passed to the
@@ -90,13 +90,15 @@ def run(statement, filename=None, sort=-1):
9090
"""
9191
return _Utils(Profile).run(statement, filename, sort)
9292

93-
def runctx(statement, globals, locals, filename=None, sort=-1):
93+
def runctx(statement, globals, locals, filename=None, sort=-1,
94+
numresults=None):
9495
"""Run statement under profiler, supplying your own globals and locals,
9596
optionally saving results in filename.
9697
9798
statement and filename have the same semantics as profile.run
9899
"""
99-
return _Utils(Profile).runctx(statement, globals, locals, filename, sort)
100+
return _Utils(Profile).runctx(statement, globals, locals, filename, sort,
101+
numresults)
100102

101103

102104
class Profile:
@@ -383,10 +385,10 @@ def simulate_cmd_complete(self):
383385
self.t = get_time() - t
384386

385387

386-
def print_stats(self, sort=-1):
388+
def print_stats(self, sort=-1, numresults=None):
387389
import pstats
388-
pstats.Stats(self).strip_dirs().sort_stats(sort). \
389-
print_stats()
390+
pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats(
391+
numresults)
390392

391393
def dump_stats(self, file):
392394
with open(file, 'wb') as f:
@@ -566,18 +568,21 @@ def f(m, f1=f1):
566568

567569
def main():
568570
import os
571+
import pstats
569572
from optparse import OptionParser
570573

571-
usage = "profile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ..."
574+
usage = "profile.py [-o output_file_path] [-s sort] [-n limit] [-m module | scriptfile] [arg] ..."
572575
parser = OptionParser(usage=usage)
573576
parser.allow_interspersed_args = False
574577
parser.add_option('-o', '--outfile', dest="outfile",
575578
help="Save stats to <outfile>", default=None)
576579
parser.add_option('-m', dest="module", action="store_true",
577580
help="Profile a library module.", default=False)
581+
parser.add_option('-n', '--numresults', dest="numresults", type="int",
582+
help="Number of results to show", default=20)
578583
parser.add_option('-s', '--sort', dest="sort",
579584
help="Sort order when printing to stdout, based on pstats.Stats class",
580-
default=-1)
585+
default='time', choices=sorted(pstats.Stats.sort_arg_dict_default))
581586

582587
if not sys.argv[1:]:
583588
parser.print_usage()
@@ -605,7 +610,8 @@ def main():
605610
'__package__': None,
606611
'__cached__': None,
607612
}
608-
runctx(code, globs, None, options.outfile, options.sort)
613+
runctx(code, globs, None, options.outfile, options.sort,
614+
options.numresults)
609615
else:
610616
parser.print_usage()
611617
return parser

0 commit comments

Comments
 (0)