hgperf
112 lines
| 2.8 KiB
| text/plain
|
TextLexer
/ contrib / hgperf
FUJIWARA Katsunori
|
r20839 | #!/usr/bin/env python | ||
# | ||||
# hgperf - measure performance of Mercurial commands | ||||
# | ||||
# Copyright 2014 Matt Mackall <mpm@selenic.com> | ||||
# | ||||
# This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | ||||
'''measure performance of Mercurial commands | ||||
Using ``hgperf`` instead of ``hg`` measures performance of the target | ||||
Mercurial command. For example, the execution below measures | ||||
performance of :hg:`heads --topo`:: | ||||
$ hgperf heads --topo | ||||
All command output via ``ui`` is suppressed, and just measurement | ||||
result is displayed: see also "perf" extension in "contrib". | ||||
Costs of processing before dispatching to the command function like | ||||
below are not measured:: | ||||
- parsing command line (e.g. option validity check) | ||||
- reading configuration files in | ||||
But ``pre-`` and ``post-`` hook invocation for the target command is | ||||
measured, even though these are invoked before or after dispatching to | ||||
the command function, because these may be required to repeat | ||||
execution of the target command correctly. | ||||
''' | ||||
import os | ||||
import sys | ||||
libdir = '@LIBDIR@' | ||||
if libdir != '@' 'LIBDIR' '@': | ||||
if not os.path.isabs(libdir): | ||||
Gregory Szorc
|
r44058 | libdir = os.path.join( | ||
os.path.dirname(os.path.realpath(__file__)), libdir | ||||
) | ||||
FUJIWARA Katsunori
|
r20839 | libdir = os.path.abspath(libdir) | ||
sys.path.insert(0, libdir) | ||||
# enable importing on demand to reduce startup time | ||||
try: | ||||
Gregory Szorc
|
r44058 | from mercurial import demandimport | ||
demandimport.enable() | ||||
FUJIWARA Katsunori
|
r20839 | except ImportError: | ||
import sys | ||||
Gregory Szorc
|
r44058 | |||
sys.stderr.write( | ||||
"abort: couldn't find mercurial libraries in [%s]\n" | ||||
% ' '.join(sys.path) | ||||
) | ||||
FUJIWARA Katsunori
|
r20839 | sys.stderr.write("(check your install and PYTHONPATH)\n") | ||
sys.exit(-1) | ||||
Augie Fackler
|
r33893 | from mercurial import ( | ||
dispatch, | ||||
util, | ||||
) | ||||
FUJIWARA Katsunori
|
r20839 | |||
Gregory Szorc
|
r44058 | |||
FUJIWARA Katsunori
|
r20839 | def timer(func, title=None): | ||
results = [] | ||||
Augie Fackler
|
r33893 | begin = util.timer() | ||
FUJIWARA Katsunori
|
r20839 | count = 0 | ||
while True: | ||||
ostart = os.times() | ||||
Augie Fackler
|
r33893 | cstart = util.timer() | ||
FUJIWARA Katsunori
|
r20839 | r = func() | ||
Augie Fackler
|
r33893 | cstop = util.timer() | ||
FUJIWARA Katsunori
|
r20839 | ostop = os.times() | ||
count += 1 | ||||
a, b = ostart, ostop | ||||
Gregory Szorc
|
r44058 | results.append((cstop - cstart, b[0] - a[0], b[1] - a[1])) | ||
FUJIWARA Katsunori
|
r20839 | if cstop - begin > 3 and count >= 100: | ||
break | ||||
if cstop - begin > 10 and count >= 3: | ||||
break | ||||
if title: | ||||
sys.stderr.write("! %s\n" % title) | ||||
if r: | ||||
sys.stderr.write("! result: %s\n" % r) | ||||
m = min(results) | ||||
Gregory Szorc
|
r44058 | sys.stderr.write( | ||
"! wall %f comb %f user %f sys %f (best of %d)\n" | ||||
% (m[0], m[1] + m[2], m[1], m[2], count) | ||||
) | ||||
FUJIWARA Katsunori
|
r20839 | |||
Augie Fackler
|
r33893 | orgruncommand = dispatch.runcommand | ||
FUJIWARA Katsunori
|
r20839 | |||
Gregory Szorc
|
r44058 | |||
FUJIWARA Katsunori
|
r20839 | def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions): | ||
ui.pushbuffer() | ||||
lui.pushbuffer() | ||||
Gregory Szorc
|
r44058 | timer( | ||
lambda: orgruncommand( | ||||
lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions | ||||
) | ||||
) | ||||
FUJIWARA Katsunori
|
r20839 | ui.popbuffer() | ||
lui.popbuffer() | ||||
Gregory Szorc
|
r44058 | |||
Augie Fackler
|
r33893 | dispatch.runcommand = runcommand | ||
FUJIWARA Katsunori
|
r20839 | |||
Augie Fackler
|
r33893 | dispatch.run() | ||