contrib/hgperf
author Siddharth Agarwal <sid0@fb.com>
Fri, 03 Oct 2014 18:45:56 -0700
changeset 22779 d9585dda63c3
parent 20839 377a111d1cd2
child 30975 22fbca1d11ed
permissions -rw-r--r--
encoding.lower: use fast ASCII lower This benefits, among other things, the case collision auditor. On a Linux system with a large real-world repo where all filenames are ASCII, hg perfcca: before: wall 0.260157 comb 0.270000 user 0.230000 sys 0.040000 (best of 38) after: wall 0.164616 comb 0.160000 user 0.160000 sys 0.000000 (best of 54)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
20839
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     1
#!/usr/bin/env python
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     2
#
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     3
# hgperf - measure performance of Mercurial commands
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     4
#
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     5
# Copyright 2014 Matt Mackall <mpm@selenic.com>
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     6
#
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     7
# This software may be used and distributed according to the terms of the
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     8
# GNU General Public License version 2 or any later version.
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
     9
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    10
'''measure performance of Mercurial commands
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    11
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    12
Using ``hgperf`` instead of ``hg`` measures performance of the target
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    13
Mercurial command. For example, the execution below measures
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    14
performance of :hg:`heads --topo`::
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    15
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    16
    $ hgperf heads --topo
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    17
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    18
All command output via ``ui`` is suppressed, and just measurement
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    19
result is displayed: see also "perf" extension in "contrib".
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    20
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    21
Costs of processing before dispatching to the command function like
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    22
below are not measured::
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    23
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    24
    - parsing command line (e.g. option validity check)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    25
    - reading configuration files in
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    26
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    27
But ``pre-`` and ``post-`` hook invocation for the target command is
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    28
measured, even though these are invoked before or after dispatching to
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    29
the command function, because these may be required to repeat
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    30
execution of the target command correctly.
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    31
'''
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    32
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    33
import os
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    34
import sys
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    35
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    36
libdir = '@LIBDIR@'
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    37
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    38
if libdir != '@' 'LIBDIR' '@':
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    39
    if not os.path.isabs(libdir):
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    40
        libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    41
                              libdir)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    42
        libdir = os.path.abspath(libdir)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    43
    sys.path.insert(0, libdir)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    44
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    45
# enable importing on demand to reduce startup time
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    46
try:
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    47
    from mercurial import demandimport; demandimport.enable()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    48
except ImportError:
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    49
    import sys
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    50
    sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" %
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    51
                     ' '.join(sys.path))
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    52
    sys.stderr.write("(check your install and PYTHONPATH)\n")
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    53
    sys.exit(-1)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    54
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    55
import mercurial.util
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    56
import mercurial.dispatch
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    57
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    58
import time
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    59
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    60
def timer(func, title=None):
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    61
    results = []
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    62
    begin = time.time()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    63
    count = 0
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    64
    while True:
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    65
        ostart = os.times()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    66
        cstart = time.time()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    67
        r = func()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    68
        cstop = time.time()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    69
        ostop = os.times()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    70
        count += 1
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    71
        a, b = ostart, ostop
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    72
        results.append((cstop - cstart, b[0] - a[0], b[1]-a[1]))
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    73
        if cstop - begin > 3 and count >= 100:
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    74
            break
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    75
        if cstop - begin > 10 and count >= 3:
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    76
            break
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    77
    if title:
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    78
        sys.stderr.write("! %s\n" % title)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    79
    if r:
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    80
        sys.stderr.write("! result: %s\n" % r)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    81
    m = min(results)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    82
    sys.stderr.write("! wall %f comb %f user %f sys %f (best of %d)\n"
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    83
                     % (m[0], m[1] + m[2], m[1], m[2], count))
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    84
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    85
orgruncommand = mercurial.dispatch.runcommand
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    86
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    87
def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    88
    ui.pushbuffer()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    89
    lui.pushbuffer()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    90
    timer(lambda : orgruncommand(lui, repo, cmd, fullargs, ui,
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    91
                                 options, d, cmdpats, cmdoptions))
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    92
    ui.popbuffer()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    93
    lui.popbuffer()
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    94
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    95
mercurial.dispatch.runcommand = runcommand
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    96
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    97
for fp in (sys.stdin, sys.stdout, sys.stderr):
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    98
    mercurial.util.setbinary(fp)
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
    99
377a111d1cd2 contrib: add "hgperf" command to measure performance of commands easily
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
   100
mercurial.dispatch.run()