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