dispatch: add support for python-flamegraph[0] profiling
This gives us nicer svg flame graphs for output, which can make
understanding some types of performance problems significantly easier.
0: https://github.com/evanhempel/python-flamegraph/
--- a/mercurial/dispatch.py Tue Apr 28 16:44:37 2015 -0400
+++ b/mercurial/dispatch.py Thu Apr 16 17:12:33 2015 -0400
@@ -921,6 +921,30 @@
stats.sort(field)
stats.pprint(limit=limit, file=fp, climit=climit)
+def flameprofile(ui, func, fp):
+ try:
+ from flamegraph import flamegraph
+ except ImportError:
+ raise util.Abort(_(
+ 'flamegraph not available - install from '
+ 'https://github.com/evanhempel/python-flamegraph'))
+ freq = ui.configint('profiling', 'freq', default=1000)
+ filter_ = None
+ collapse_recursion = True
+ thread = flamegraph.ProfileThread(fp, 1.0 / freq,
+ filter_, collapse_recursion)
+ start_time = time.clock()
+ try:
+ thread.start()
+ func()
+ finally:
+ thread.stop()
+ thread.join()
+ print 'Collected %d stack frames (%d unique) in %2.2f seconds.' % (
+ time.clock() - start_time, thread.num_frames(),
+ thread.num_frames(unique=True))
+
+
def statprofile(ui, func, fp):
try:
import statprof
@@ -952,7 +976,7 @@
profiler = os.getenv('HGPROF')
if profiler is None:
profiler = ui.config('profiling', 'type', default='ls')
- if profiler not in ('ls', 'stat'):
+ if profiler not in ('ls', 'stat', 'flame'):
ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
profiler = 'ls'
@@ -967,6 +991,8 @@
try:
if profiler == 'ls':
return lsprofile(ui, checkargs, fp)
+ elif profiler == 'flame':
+ return flameprofile(ui, checkargs, fp)
else:
return statprofile(ui, checkargs, fp)
finally: