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