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