comparison contrib/perf.py @ 23171:8afae1d5d108

perf: use a formatter for output We use a `formatter` object in the perf extensions. This allow the use of formatted output like json. To avoid adding logic to create a formatter and pass it around to the timer function in every command, we add a `gettimer` function in charge of returning a `timer` function as simple as before but embedding an appropriate formatter. This new `gettimer` function also return the formatter as it needs to be explicitly closed at the end of the command. example output: $ hg --config ui.formatjson=True perfvolatilesets visible obsolete [ { "comb": 0.02, "count": 126, "sys": 0.0, "title": "obsolete", "user": 0.02, "wall": 0.0199398994446 }, { "comb": 0.02, "count": 117, "sys": 0.0, "title": "visible", "user": 0.02, "wall": 0.0250301361084 } ]
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 04 Nov 2014 10:40:06 +0000
parents d8ff1f671aed
children ccb93e9affc1
comparison
equal deleted inserted replaced
23170:02e8f9b60052 23171:8afae1d5d108
2 '''helper extension to measure performance''' 2 '''helper extension to measure performance'''
3 3
4 from mercurial import cmdutil, scmutil, util, commands, obsolete 4 from mercurial import cmdutil, scmutil, util, commands, obsolete
5 from mercurial import repoview, branchmap, merge, copies 5 from mercurial import repoview, branchmap, merge, copies
6 import time, os, sys 6 import time, os, sys
7 import functools
7 8
8 cmdtable = {} 9 cmdtable = {}
9 command = cmdutil.command(cmdtable) 10 command = cmdutil.command(cmdtable)
10 11
11 def timer(func, title=None): 12 def gettimer(ui, opts=None):
13 """return a timer function and formatter: (timer, formatter)
14
15 This functions exist to gather the creation of formatter in a single
16 place instead of duplicating it in all performance command."""
17 if opts is None:
18 opts = {}
19 # redirect all to stderr
20 ui = ui.copy()
21 ui.fout = ui.ferr
22 # get a formatter
23 fm = ui.formatter('perf', opts)
24 return functools.partial(_timer, fm), fm
25
26 def _timer(fm, func, title=None):
12 results = [] 27 results = []
13 begin = time.time() 28 begin = time.time()
14 count = 0 29 count = 0
15 while True: 30 while True:
16 ostart = os.times() 31 ostart = os.times()
23 results.append((cstop - cstart, b[0] - a[0], b[1]-a[1])) 38 results.append((cstop - cstart, b[0] - a[0], b[1]-a[1]))
24 if cstop - begin > 3 and count >= 100: 39 if cstop - begin > 3 and count >= 100:
25 break 40 break
26 if cstop - begin > 10 and count >= 3: 41 if cstop - begin > 10 and count >= 3:
27 break 42 break
43
44 fm.startitem()
45
28 if title: 46 if title:
29 sys.stderr.write("! %s\n" % title) 47 fm.write('title', '! %s\n', title)
30 if r: 48 if r:
31 sys.stderr.write("! result: %s\n" % r) 49 fm.write('result', '! result: %s\n', r)
32 m = min(results) 50 m = min(results)
33 sys.stderr.write("! wall %f comb %f user %f sys %f (best of %d)\n" 51 fm.plain('!')
34 % (m[0], m[1] + m[2], m[1], m[2], count)) 52 fm.write('wall', ' wall %f', m[0])
53 fm.write('comb', ' comb %f', m[1] + m[2])
54 fm.write('user', ' user %f', m[1])
55 fm.write('sys', ' sys %f', m[2])
56 fm.write('count', ' (best of %d)', count)
57 fm.plain('\n')
35 58
36 @command('perfwalk') 59 @command('perfwalk')
37 def perfwalk(ui, repo, *pats): 60 def perfwalk(ui, repo, *pats):
61 timer, fm = gettimer(ui)
38 try: 62 try:
39 m = scmutil.match(repo[None], pats, {}) 63 m = scmutil.match(repo[None], pats, {})
40 timer(lambda: len(list(repo.dirstate.walk(m, [], True, False)))) 64 timer(lambda: len(list(repo.dirstate.walk(m, [], True, False))))
41 except Exception: 65 except Exception:
42 try: 66 try:
43 m = scmutil.match(repo[None], pats, {}) 67 m = scmutil.match(repo[None], pats, {})
44 timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)])) 68 timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)]))
45 except Exception: 69 except Exception:
46 timer(lambda: len(list(cmdutil.walk(repo, pats, {})))) 70 timer(lambda: len(list(cmdutil.walk(repo, pats, {}))))
71 fm.end()
47 72
48 @command('perfannotate') 73 @command('perfannotate')
49 def perfannotate(ui, repo, f): 74 def perfannotate(ui, repo, f):
75 timer, fm = gettimer(ui)
50 fc = repo['.'][f] 76 fc = repo['.'][f]
51 timer(lambda: len(fc.annotate(True))) 77 timer(lambda: len(fc.annotate(True)))
78 fm.end()
52 79
53 @command('perfstatus', 80 @command('perfstatus',
54 [('u', 'unknown', False, 81 [('u', 'unknown', False,
55 'ask status to look for unknown files')]) 82 'ask status to look for unknown files')])
56 def perfstatus(ui, repo, **opts): 83 def perfstatus(ui, repo, **opts):
57 #m = match.always(repo.root, repo.getcwd()) 84 #m = match.always(repo.root, repo.getcwd())
58 #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False, 85 #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False,
59 # False)))) 86 # False))))
87 timer, fm = gettimer(ui)
60 timer(lambda: sum(map(len, repo.status(**opts)))) 88 timer(lambda: sum(map(len, repo.status(**opts))))
89 fm.end()
61 90
62 @command('perfaddremove') 91 @command('perfaddremove')
63 def perfaddremove(ui, repo): 92 def perfaddremove(ui, repo):
93 timer, fm = gettimer(ui)
64 try: 94 try:
65 oldquiet = repo.ui.quiet 95 oldquiet = repo.ui.quiet
66 repo.ui.quiet = True 96 repo.ui.quiet = True
67 timer(lambda: scmutil.addremove(repo, dry_run=True)) 97 timer(lambda: scmutil.addremove(repo, dry_run=True))
68 finally: 98 finally:
69 repo.ui.quiet = oldquiet 99 repo.ui.quiet = oldquiet
100 fm.end()
70 101
71 def clearcaches(cl): 102 def clearcaches(cl):
72 # behave somewhat consistently across internal API changes 103 # behave somewhat consistently across internal API changes
73 if util.safehasattr(cl, 'clearcaches'): 104 if util.safehasattr(cl, 'clearcaches'):
74 cl.clearcaches() 105 cl.clearcaches()
77 cl._nodecache = {nullid: nullrev} 108 cl._nodecache = {nullid: nullrev}
78 cl._nodepos = None 109 cl._nodepos = None
79 110
80 @command('perfheads') 111 @command('perfheads')
81 def perfheads(ui, repo): 112 def perfheads(ui, repo):
113 timer, fm = gettimer(ui)
82 cl = repo.changelog 114 cl = repo.changelog
83 def d(): 115 def d():
84 len(cl.headrevs()) 116 len(cl.headrevs())
85 clearcaches(cl) 117 clearcaches(cl)
86 timer(d) 118 timer(d)
119 fm.end()
87 120
88 @command('perftags') 121 @command('perftags')
89 def perftags(ui, repo): 122 def perftags(ui, repo):
90 import mercurial.changelog 123 import mercurial.changelog
91 import mercurial.manifest 124 import mercurial.manifest
125 timer, fm = gettimer(ui)
92 def t(): 126 def t():
93 repo.changelog = mercurial.changelog.changelog(repo.sopener) 127 repo.changelog = mercurial.changelog.changelog(repo.sopener)
94 repo.manifest = mercurial.manifest.manifest(repo.sopener) 128 repo.manifest = mercurial.manifest.manifest(repo.sopener)
95 repo._tags = None 129 repo._tags = None
96 return len(repo.tags()) 130 return len(repo.tags())
97 timer(t) 131 timer(t)
132 fm.end()
98 133
99 @command('perfancestors') 134 @command('perfancestors')
100 def perfancestors(ui, repo): 135 def perfancestors(ui, repo):
136 timer, fm = gettimer(ui)
101 heads = repo.changelog.headrevs() 137 heads = repo.changelog.headrevs()
102 def d(): 138 def d():
103 for a in repo.changelog.ancestors(heads): 139 for a in repo.changelog.ancestors(heads):
104 pass 140 pass
105 timer(d) 141 timer(d)
142 fm.end()
106 143
107 @command('perfancestorset') 144 @command('perfancestorset')
108 def perfancestorset(ui, repo, revset): 145 def perfancestorset(ui, repo, revset):
146 timer, fm = gettimer(ui)
109 revs = repo.revs(revset) 147 revs = repo.revs(revset)
110 heads = repo.changelog.headrevs() 148 heads = repo.changelog.headrevs()
111 def d(): 149 def d():
112 s = repo.changelog.ancestors(heads) 150 s = repo.changelog.ancestors(heads)
113 for rev in revs: 151 for rev in revs:
114 rev in s 152 rev in s
115 timer(d) 153 timer(d)
154 fm.end()
116 155
117 @command('perfdirs') 156 @command('perfdirs')
118 def perfdirs(ui, repo): 157 def perfdirs(ui, repo):
158 timer, fm = gettimer(ui)
119 dirstate = repo.dirstate 159 dirstate = repo.dirstate
120 'a' in dirstate 160 'a' in dirstate
121 def d(): 161 def d():
122 dirstate.dirs() 162 dirstate.dirs()
123 del dirstate._dirs 163 del dirstate._dirs
124 timer(d) 164 timer(d)
165 fm.end()
125 166
126 @command('perfdirstate') 167 @command('perfdirstate')
127 def perfdirstate(ui, repo): 168 def perfdirstate(ui, repo):
169 timer, fm = gettimer(ui)
128 "a" in repo.dirstate 170 "a" in repo.dirstate
129 def d(): 171 def d():
130 repo.dirstate.invalidate() 172 repo.dirstate.invalidate()
131 "a" in repo.dirstate 173 "a" in repo.dirstate
132 timer(d) 174 timer(d)
175 fm.end()
133 176
134 @command('perfdirstatedirs') 177 @command('perfdirstatedirs')
135 def perfdirstatedirs(ui, repo): 178 def perfdirstatedirs(ui, repo):
179 timer, fm = gettimer(ui)
136 "a" in repo.dirstate 180 "a" in repo.dirstate
137 def d(): 181 def d():
138 "a" in repo.dirstate._dirs 182 "a" in repo.dirstate._dirs
139 del repo.dirstate._dirs 183 del repo.dirstate._dirs
140 timer(d) 184 timer(d)
185 fm.end()
141 186
142 @command('perfdirstatefoldmap') 187 @command('perfdirstatefoldmap')
143 def perffoldmap(ui, repo): 188 def perffoldmap(ui, repo):
189 timer, fm = gettimer(ui)
144 dirstate = repo.dirstate 190 dirstate = repo.dirstate
145 'a' in dirstate 191 'a' in dirstate
146 def d(): 192 def d():
147 dirstate._foldmap.get('a') 193 dirstate._foldmap.get('a')
148 del dirstate._foldmap 194 del dirstate._foldmap
149 del dirstate._dirs 195 del dirstate._dirs
150 timer(d) 196 timer(d)
197 fm.end()
151 198
152 @command('perfdirstatewrite') 199 @command('perfdirstatewrite')
153 def perfdirstatewrite(ui, repo): 200 def perfdirstatewrite(ui, repo):
201 timer, fm = gettimer(ui)
154 ds = repo.dirstate 202 ds = repo.dirstate
155 "a" in ds 203 "a" in ds
156 def d(): 204 def d():
157 ds._dirty = True 205 ds._dirty = True
158 ds.write() 206 ds.write()
159 timer(d) 207 timer(d)
208 fm.end()
160 209
161 @command('perfmergecalculate', 210 @command('perfmergecalculate',
162 [('r', 'rev', '.', 'rev to merge against')]) 211 [('r', 'rev', '.', 'rev to merge against')])
163 def perfmergecalculate(ui, repo, rev): 212 def perfmergecalculate(ui, repo, rev):
213 timer, fm = gettimer(ui)
164 wctx = repo[None] 214 wctx = repo[None]
165 rctx = scmutil.revsingle(repo, rev, rev) 215 rctx = scmutil.revsingle(repo, rev, rev)
166 ancestor = wctx.ancestor(rctx) 216 ancestor = wctx.ancestor(rctx)
167 # we don't want working dir files to be stat'd in the benchmark, so prime 217 # we don't want working dir files to be stat'd in the benchmark, so prime
168 # that cache 218 # that cache
171 # acceptremote is True because we don't want prompts in the middle of 221 # acceptremote is True because we don't want prompts in the middle of
172 # our benchmark 222 # our benchmark
173 merge.calculateupdates(repo, wctx, rctx, ancestor, False, False, False, 223 merge.calculateupdates(repo, wctx, rctx, ancestor, False, False, False,
174 acceptremote=True) 224 acceptremote=True)
175 timer(d) 225 timer(d)
226 fm.end()
176 227
177 @command('perfpathcopies', [], "REV REV") 228 @command('perfpathcopies', [], "REV REV")
178 def perfpathcopies(ui, repo, rev1, rev2): 229 def perfpathcopies(ui, repo, rev1, rev2):
230 timer, fm = gettimer(ui)
179 ctx1 = scmutil.revsingle(repo, rev1, rev1) 231 ctx1 = scmutil.revsingle(repo, rev1, rev1)
180 ctx2 = scmutil.revsingle(repo, rev2, rev2) 232 ctx2 = scmutil.revsingle(repo, rev2, rev2)
181 def d(): 233 def d():
182 copies.pathcopies(ctx1, ctx2) 234 copies.pathcopies(ctx1, ctx2)
183 timer(d) 235 timer(d)
236 fm.end()
184 237
185 @command('perfmanifest', [], 'REV') 238 @command('perfmanifest', [], 'REV')
186 def perfmanifest(ui, repo, rev): 239 def perfmanifest(ui, repo, rev):
240 timer, fm = gettimer(ui)
187 ctx = scmutil.revsingle(repo, rev, rev) 241 ctx = scmutil.revsingle(repo, rev, rev)
188 t = ctx.manifestnode() 242 t = ctx.manifestnode()
189 def d(): 243 def d():
190 repo.manifest._mancache.clear() 244 repo.manifest._mancache.clear()
191 repo.manifest._cache = None 245 repo.manifest._cache = None
192 repo.manifest.read(t) 246 repo.manifest.read(t)
193 timer(d) 247 timer(d)
248 fm.end()
194 249
195 @command('perfchangeset') 250 @command('perfchangeset')
196 def perfchangeset(ui, repo, rev): 251 def perfchangeset(ui, repo, rev):
252 timer, fm = gettimer(ui)
197 n = repo[rev].node() 253 n = repo[rev].node()
198 def d(): 254 def d():
199 repo.changelog.read(n) 255 repo.changelog.read(n)
200 #repo.changelog._cache = None 256 #repo.changelog._cache = None
201 timer(d) 257 timer(d)
258 fm.end()
202 259
203 @command('perfindex') 260 @command('perfindex')
204 def perfindex(ui, repo): 261 def perfindex(ui, repo):
205 import mercurial.revlog 262 import mercurial.revlog
263 timer, fm = gettimer(ui)
206 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg 264 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
207 n = repo["tip"].node() 265 n = repo["tip"].node()
208 def d(): 266 def d():
209 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i") 267 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i")
210 cl.rev(n) 268 cl.rev(n)
211 timer(d) 269 timer(d)
270 fm.end()
212 271
213 @command('perfstartup') 272 @command('perfstartup')
214 def perfstartup(ui, repo): 273 def perfstartup(ui, repo):
274 timer, fm = gettimer(ui)
215 cmd = sys.argv[0] 275 cmd = sys.argv[0]
216 def d(): 276 def d():
217 os.system("HGRCPATH= %s version -q > /dev/null" % cmd) 277 os.system("HGRCPATH= %s version -q > /dev/null" % cmd)
218 timer(d) 278 timer(d)
279 fm.end()
219 280
220 @command('perfparents') 281 @command('perfparents')
221 def perfparents(ui, repo): 282 def perfparents(ui, repo):
283 timer, fm = gettimer(ui)
222 nl = [repo.changelog.node(i) for i in xrange(1000)] 284 nl = [repo.changelog.node(i) for i in xrange(1000)]
223 def d(): 285 def d():
224 for n in nl: 286 for n in nl:
225 repo.changelog.parents(n) 287 repo.changelog.parents(n)
226 timer(d) 288 timer(d)
289 fm.end()
227 290
228 @command('perflookup') 291 @command('perflookup')
229 def perflookup(ui, repo, rev): 292 def perflookup(ui, repo, rev):
293 timer, fm = gettimer(ui)
230 timer(lambda: len(repo.lookup(rev))) 294 timer(lambda: len(repo.lookup(rev)))
295 fm.end()
231 296
232 @command('perfrevrange') 297 @command('perfrevrange')
233 def perfrevrange(ui, repo, *specs): 298 def perfrevrange(ui, repo, *specs):
299 timer, fm = gettimer(ui)
234 revrange = scmutil.revrange 300 revrange = scmutil.revrange
235 timer(lambda: len(revrange(repo, specs))) 301 timer(lambda: len(revrange(repo, specs)))
302 fm.end()
236 303
237 @command('perfnodelookup') 304 @command('perfnodelookup')
238 def perfnodelookup(ui, repo, rev): 305 def perfnodelookup(ui, repo, rev):
306 timer, fm = gettimer(ui)
239 import mercurial.revlog 307 import mercurial.revlog
240 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg 308 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
241 n = repo[rev].node() 309 n = repo[rev].node()
242 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i") 310 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i")
243 def d(): 311 def d():
244 cl.rev(n) 312 cl.rev(n)
245 clearcaches(cl) 313 clearcaches(cl)
246 timer(d) 314 timer(d)
315 fm.end()
247 316
248 @command('perflog', 317 @command('perflog',
249 [('', 'rename', False, 'ask log to follow renames')]) 318 [('', 'rename', False, 'ask log to follow renames')])
250 def perflog(ui, repo, **opts): 319 def perflog(ui, repo, **opts):
320 timer, fm = gettimer(ui)
251 ui.pushbuffer() 321 ui.pushbuffer()
252 timer(lambda: commands.log(ui, repo, rev=[], date='', user='', 322 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
253 copies=opts.get('rename'))) 323 copies=opts.get('rename')))
254 ui.popbuffer() 324 ui.popbuffer()
325 fm.end()
255 326
256 @command('perfmoonwalk') 327 @command('perfmoonwalk')
257 def perfmoonwalk(ui, repo): 328 def perfmoonwalk(ui, repo):
258 """benchmark walking the changelog backwards 329 """benchmark walking the changelog backwards
259 330
260 This also loads the changelog data for each revision in the changelog. 331 This also loads the changelog data for each revision in the changelog.
261 """ 332 """
333 timer, fm = gettimer(ui)
262 def moonwalk(): 334 def moonwalk():
263 for i in xrange(len(repo), -1, -1): 335 for i in xrange(len(repo), -1, -1):
264 ctx = repo[i] 336 ctx = repo[i]
265 ctx.branch() # read changelog data (in addition to the index) 337 ctx.branch() # read changelog data (in addition to the index)
266 timer(moonwalk) 338 timer(moonwalk)
339 fm.end()
267 340
268 @command('perftemplating') 341 @command('perftemplating')
269 def perftemplating(ui, repo): 342 def perftemplating(ui, repo):
343 timer, fm = gettimer(ui)
270 ui.pushbuffer() 344 ui.pushbuffer()
271 timer(lambda: commands.log(ui, repo, rev=[], date='', user='', 345 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
272 template='{date|shortdate} [{rev}:{node|short}]' 346 template='{date|shortdate} [{rev}:{node|short}]'
273 ' {author|person}: {desc|firstline}\n')) 347 ' {author|person}: {desc|firstline}\n'))
274 ui.popbuffer() 348 ui.popbuffer()
349 fm.end()
275 350
276 @command('perfcca') 351 @command('perfcca')
277 def perfcca(ui, repo): 352 def perfcca(ui, repo):
353 timer, fm = gettimer(ui)
278 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate)) 354 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
355 fm.end()
279 356
280 @command('perffncacheload') 357 @command('perffncacheload')
281 def perffncacheload(ui, repo): 358 def perffncacheload(ui, repo):
359 timer, fm = gettimer(ui)
282 s = repo.store 360 s = repo.store
283 def d(): 361 def d():
284 s.fncache._load() 362 s.fncache._load()
285 timer(d) 363 timer(d)
364 fm.end()
286 365
287 @command('perffncachewrite') 366 @command('perffncachewrite')
288 def perffncachewrite(ui, repo): 367 def perffncachewrite(ui, repo):
368 timer, fm = gettimer(ui)
289 s = repo.store 369 s = repo.store
290 s.fncache._load() 370 s.fncache._load()
291 def d(): 371 def d():
292 s.fncache._dirty = True 372 s.fncache._dirty = True
293 s.fncache.write() 373 s.fncache.write()
294 timer(d) 374 timer(d)
375 fm.end()
295 376
296 @command('perffncacheencode') 377 @command('perffncacheencode')
297 def perffncacheencode(ui, repo): 378 def perffncacheencode(ui, repo):
379 timer, fm = gettimer(ui)
298 s = repo.store 380 s = repo.store
299 s.fncache._load() 381 s.fncache._load()
300 def d(): 382 def d():
301 for p in s.fncache.entries: 383 for p in s.fncache.entries:
302 s.encode(p) 384 s.encode(p)
303 timer(d) 385 timer(d)
386 fm.end()
304 387
305 @command('perfdiffwd') 388 @command('perfdiffwd')
306 def perfdiffwd(ui, repo): 389 def perfdiffwd(ui, repo):
307 """Profile diff of working directory changes""" 390 """Profile diff of working directory changes"""
391 timer, fm = gettimer(ui)
308 options = { 392 options = {
309 'w': 'ignore_all_space', 393 'w': 'ignore_all_space',
310 'b': 'ignore_space_change', 394 'b': 'ignore_space_change',
311 'B': 'ignore_blank_lines', 395 'B': 'ignore_blank_lines',
312 } 396 }
317 ui.pushbuffer() 401 ui.pushbuffer()
318 commands.diff(ui, repo, **opts) 402 commands.diff(ui, repo, **opts)
319 ui.popbuffer() 403 ui.popbuffer()
320 title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none') 404 title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none')
321 timer(d, title) 405 timer(d, title)
406 fm.end()
322 407
323 @command('perfrevlog', 408 @command('perfrevlog',
324 [('d', 'dist', 100, 'distance between the revisions')], 409 [('d', 'dist', 100, 'distance between the revisions')],
325 "[INDEXFILE]") 410 "[INDEXFILE]")
326 def perfrevlog(ui, repo, file_, **opts): 411 def perfrevlog(ui, repo, file_, **opts):
412 timer, fm = gettimer(ui)
327 from mercurial import revlog 413 from mercurial import revlog
328 dist = opts['dist'] 414 dist = opts['dist']
329 def d(): 415 def d():
330 r = revlog.revlog(lambda fn: open(fn, 'rb'), file_) 416 r = revlog.revlog(lambda fn: open(fn, 'rb'), file_)
331 for x in xrange(0, len(r), dist): 417 for x in xrange(0, len(r), dist):
332 r.revision(r.node(x)) 418 r.revision(r.node(x))
333 419
334 timer(d) 420 timer(d)
421 fm.end()
335 422
336 @command('perfrevset', 423 @command('perfrevset',
337 [('C', 'clear', False, 'clear volatile cache between each call.')], 424 [('C', 'clear', False, 'clear volatile cache between each call.')],
338 "REVSET") 425 "REVSET")
339 def perfrevset(ui, repo, expr, clear=False): 426 def perfrevset(ui, repo, expr, clear=False):
340 """benchmark the execution time of a revset 427 """benchmark the execution time of a revset
341 428
342 Use the --clean option if need to evaluate the impact of build volatile 429 Use the --clean option if need to evaluate the impact of build volatile
343 revisions set cache on the revset execution. Volatile cache hold filtered 430 revisions set cache on the revset execution. Volatile cache hold filtered
344 and obsolete related cache.""" 431 and obsolete related cache."""
432 timer, fm = gettimer(ui)
345 def d(): 433 def d():
346 if clear: 434 if clear:
347 repo.invalidatevolatilesets() 435 repo.invalidatevolatilesets()
348 for r in repo.revs(expr): pass 436 for r in repo.revs(expr): pass
349 timer(d) 437 timer(d)
438 fm.end()
350 439
351 @command('perfvolatilesets') 440 @command('perfvolatilesets')
352 def perfvolatilesets(ui, repo, *names): 441 def perfvolatilesets(ui, repo, *names):
353 """benchmark the computation of various volatile set 442 """benchmark the computation of various volatile set
354 443
355 Volatile set computes element related to filtering and obsolescence.""" 444 Volatile set computes element related to filtering and obsolescence."""
445 timer, fm = gettimer(ui)
356 repo = repo.unfiltered() 446 repo = repo.unfiltered()
357 447
358 def getobs(name): 448 def getobs(name):
359 def d(): 449 def d():
360 repo.invalidatevolatilesets() 450 repo.invalidatevolatilesets()
378 if names: 468 if names:
379 allfilter = [n for n in allfilter if n in names] 469 allfilter = [n for n in allfilter if n in names]
380 470
381 for name in allfilter: 471 for name in allfilter:
382 timer(getfiltered(name), title=name) 472 timer(getfiltered(name), title=name)
473 fm.end()
383 474
384 @command('perfbranchmap', 475 @command('perfbranchmap',
385 [('f', 'full', False, 476 [('f', 'full', False,
386 'Includes build time of subset'), 477 'Includes build time of subset'),
387 ]) 478 ])
388 def perfbranchmap(ui, repo, full=False): 479 def perfbranchmap(ui, repo, full=False):
389 """benchmark the update of a branchmap 480 """benchmark the update of a branchmap
390 481
391 This benchmarks the full repo.branchmap() call with read and write disabled 482 This benchmarks the full repo.branchmap() call with read and write disabled
392 """ 483 """
484 timer, fm = gettimer(ui)
393 def getbranchmap(filtername): 485 def getbranchmap(filtername):
394 """generate a benchmark function for the filtername""" 486 """generate a benchmark function for the filtername"""
395 if filtername is None: 487 if filtername is None:
396 view = repo 488 view = repo
397 else: 489 else:
430 for name in allfilters: 522 for name in allfilters:
431 timer(getbranchmap(name), title=str(name)) 523 timer(getbranchmap(name), title=str(name))
432 finally: 524 finally:
433 branchmap.read = oldread 525 branchmap.read = oldread
434 branchmap.branchcache.write = oldwrite 526 branchmap.branchcache.write = oldwrite
527 fm.end()