##// END OF EJS Templates
hgperf: update to conform with import style checks
Augie Fackler -
r33893:78f644fd default
parent child Browse files
Show More
@@ -1,98 +1,100
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # hgperf - measure performance of Mercurial commands
3 # hgperf - measure performance of Mercurial commands
4 #
4 #
5 # Copyright 2014 Matt Mackall <mpm@selenic.com>
5 # Copyright 2014 Matt Mackall <mpm@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms of the
7 # This software may be used and distributed according to the terms of the
8 # GNU General Public License version 2 or any later version.
8 # GNU General Public License version 2 or any later version.
9
9
10 '''measure performance of Mercurial commands
10 '''measure performance of Mercurial commands
11
11
12 Using ``hgperf`` instead of ``hg`` measures performance of the target
12 Using ``hgperf`` instead of ``hg`` measures performance of the target
13 Mercurial command. For example, the execution below measures
13 Mercurial command. For example, the execution below measures
14 performance of :hg:`heads --topo`::
14 performance of :hg:`heads --topo`::
15
15
16 $ hgperf heads --topo
16 $ hgperf heads --topo
17
17
18 All command output via ``ui`` is suppressed, and just measurement
18 All command output via ``ui`` is suppressed, and just measurement
19 result is displayed: see also "perf" extension in "contrib".
19 result is displayed: see also "perf" extension in "contrib".
20
20
21 Costs of processing before dispatching to the command function like
21 Costs of processing before dispatching to the command function like
22 below are not measured::
22 below are not measured::
23
23
24 - parsing command line (e.g. option validity check)
24 - parsing command line (e.g. option validity check)
25 - reading configuration files in
25 - reading configuration files in
26
26
27 But ``pre-`` and ``post-`` hook invocation for the target command is
27 But ``pre-`` and ``post-`` hook invocation for the target command is
28 measured, even though these are invoked before or after dispatching to
28 measured, even though these are invoked before or after dispatching to
29 the command function, because these may be required to repeat
29 the command function, because these may be required to repeat
30 execution of the target command correctly.
30 execution of the target command correctly.
31 '''
31 '''
32
32
33 import os
33 import os
34 import sys
34 import sys
35
35
36 libdir = '@LIBDIR@'
36 libdir = '@LIBDIR@'
37
37
38 if libdir != '@' 'LIBDIR' '@':
38 if libdir != '@' 'LIBDIR' '@':
39 if not os.path.isabs(libdir):
39 if not os.path.isabs(libdir):
40 libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
40 libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
41 libdir)
41 libdir)
42 libdir = os.path.abspath(libdir)
42 libdir = os.path.abspath(libdir)
43 sys.path.insert(0, libdir)
43 sys.path.insert(0, libdir)
44
44
45 # enable importing on demand to reduce startup time
45 # enable importing on demand to reduce startup time
46 try:
46 try:
47 from mercurial import demandimport; demandimport.enable()
47 from mercurial import demandimport; demandimport.enable()
48 except ImportError:
48 except ImportError:
49 import sys
49 import sys
50 sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" %
50 sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" %
51 ' '.join(sys.path))
51 ' '.join(sys.path))
52 sys.stderr.write("(check your install and PYTHONPATH)\n")
52 sys.stderr.write("(check your install and PYTHONPATH)\n")
53 sys.exit(-1)
53 sys.exit(-1)
54
54
55 import mercurial.util
55 from mercurial import (
56 import mercurial.dispatch
56 dispatch,
57 util,
58 )
57
59
58 def timer(func, title=None):
60 def timer(func, title=None):
59 results = []
61 results = []
60 begin = mercurial.util.timer()
62 begin = util.timer()
61 count = 0
63 count = 0
62 while True:
64 while True:
63 ostart = os.times()
65 ostart = os.times()
64 cstart = mercurial.util.timer()
66 cstart = util.timer()
65 r = func()
67 r = func()
66 cstop = mercurial.util.timer()
68 cstop = util.timer()
67 ostop = os.times()
69 ostop = os.times()
68 count += 1
70 count += 1
69 a, b = ostart, ostop
71 a, b = ostart, ostop
70 results.append((cstop - cstart, b[0] - a[0], b[1]-a[1]))
72 results.append((cstop - cstart, b[0] - a[0], b[1]-a[1]))
71 if cstop - begin > 3 and count >= 100:
73 if cstop - begin > 3 and count >= 100:
72 break
74 break
73 if cstop - begin > 10 and count >= 3:
75 if cstop - begin > 10 and count >= 3:
74 break
76 break
75 if title:
77 if title:
76 sys.stderr.write("! %s\n" % title)
78 sys.stderr.write("! %s\n" % title)
77 if r:
79 if r:
78 sys.stderr.write("! result: %s\n" % r)
80 sys.stderr.write("! result: %s\n" % r)
79 m = min(results)
81 m = min(results)
80 sys.stderr.write("! wall %f comb %f user %f sys %f (best of %d)\n"
82 sys.stderr.write("! wall %f comb %f user %f sys %f (best of %d)\n"
81 % (m[0], m[1] + m[2], m[1], m[2], count))
83 % (m[0], m[1] + m[2], m[1], m[2], count))
82
84
83 orgruncommand = mercurial.dispatch.runcommand
85 orgruncommand = dispatch.runcommand
84
86
85 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
87 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
86 ui.pushbuffer()
88 ui.pushbuffer()
87 lui.pushbuffer()
89 lui.pushbuffer()
88 timer(lambda : orgruncommand(lui, repo, cmd, fullargs, ui,
90 timer(lambda : orgruncommand(lui, repo, cmd, fullargs, ui,
89 options, d, cmdpats, cmdoptions))
91 options, d, cmdpats, cmdoptions))
90 ui.popbuffer()
92 ui.popbuffer()
91 lui.popbuffer()
93 lui.popbuffer()
92
94
93 mercurial.dispatch.runcommand = runcommand
95 dispatch.runcommand = runcommand
94
96
95 for fp in (sys.stdin, sys.stdout, sys.stderr):
97 for fp in (sys.stdin, sys.stdout, sys.stderr):
96 mercurial.util.setbinary(fp)
98 util.setbinary(fp)
97
99
98 mercurial.dispatch.run()
100 dispatch.run()
General Comments 0
You need to be logged in to leave comments. Login now