Patchwork [8,of,9,RFC] profiling: use vendored statprof and upstream enhancements (BC)

login
register
mail settings
Submitter Gregory Szorc
Date Aug. 16, 2016, 5:25 a.m.
Message ID <1975493743c5f68f28bf.1471325115@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/16313/
State Superseded
Headers show

Comments

Gregory Szorc - Aug. 16, 2016, 5:25 a.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1471230897 25200
#      Sun Aug 14 20:14:57 2016 -0700
# Node ID 1975493743c5f68f28bf9dcf677df09d0265581a
# Parent  2e162a802b1f2bbcf60e29720dae1337707d842a
profiling: use vendored statprof and upstream enhancements (BC)

Now that the statprof module is vendored and suitable for use, we
switch our statprof profiler to use it. This required some changes
because of API changes between the official statprof profiler and
our vendored copy.

We also incorporate Facebook's improvements from the "statprofext"
extension at
https://bitbucket.org/facebook/hg-experimental, notably support for
different display formats.

Because statprof output is different, this is marked as BC. Although
most users likely won't notice since most users don't profile.

Patch

diff --git a/mercurial/profiling.py b/mercurial/profiling.py
--- a/mercurial/profiling.py
+++ b/mercurial/profiling.py
@@ -75,36 +75,45 @@  def flameprofile(ui, fp):
         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)))
 
 @contextlib.contextmanager
 def statprofile(ui, fp):
-    try:
-        import statprof
-    except ImportError:
-        raise error.Abort(_(
-            'statprof not available - install using "easy_install statprof"'))
+    from . import statprof
 
     freq = ui.configint('profiling', 'freq', default=1000)
     if freq > 0:
         # Cannot reset when profiler is already active. So silently no-op.
         if statprof.state.profile_level == 0:
             statprof.reset(freq)
     else:
         ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
 
-    statprof.start()
+    mechanism = ui.config('statprof', 'mechanism', 'thread')
+    statprof.start(mechanism=mechanism)
+
     try:
         yield
     finally:
-        statprof.stop()
-        statprof.display(fp)
+        data = statprof.stop()
+
+        profformat = ui.config('statprof', 'format', 'hotpath')
+
+        if profformat == 'hotpath':
+            displayformat = statprof.DisplayFormats.Hotpath
+        elif profformat == 'json':
+            displayformat = statprof.DisplayFormats.Json
+        else:
+            ui.warn(_('unknown profiler output format: %s') % profformat)
+            displayformat = statprof.DisplayFormats.Hotpath
+
+        statprof.display(fp, data=data, format=displayformat)
 
 @contextlib.contextmanager
 def profile(ui):
     """Start profiling.
 
     Profiling is active when the context manager is active. When the context
     manager exits, profiling results will be written to the configured output.
     """