##// END OF EJS Templates
contrib/perf: perfparents handle filtered repos
timeless -
r27100:8d5dba93 default
parent child Browse files
Show More
@@ -1,583 +1,584 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, error
5 from mercurial import repoview, branchmap, merge, copies, error
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 perfdirstatefoldmap(ui, repo, **opts):
196 def perfdirstatefoldmap(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,
242 merge.calculateupdates(repo, wctx, rctx, [ancestor], False, False,
243 False, acceptremote=True, followcopies=True)
243 False, acceptremote=True, followcopies=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 if len(repo.changelog) < 1000:
303 if len(repo.changelog) < 1000:
304 raise error.Abort("repo needs 1000 commits for this test")
304 raise error.Abort("repo needs 1000 commits for this test")
305 repo = repo.unfiltered()
305 nl = [repo.changelog.node(i) for i in xrange(1000)]
306 nl = [repo.changelog.node(i) for i in xrange(1000)]
306 def d():
307 def d():
307 for n in nl:
308 for n in nl:
308 repo.changelog.parents(n)
309 repo.changelog.parents(n)
309 timer(d)
310 timer(d)
310 fm.end()
311 fm.end()
311
312
312 @command('perfctxfiles', formatteropts)
313 @command('perfctxfiles', formatteropts)
313 def perfctxfiles(ui, repo, x, **opts):
314 def perfctxfiles(ui, repo, x, **opts):
314 x = int(x)
315 x = int(x)
315 timer, fm = gettimer(ui, opts)
316 timer, fm = gettimer(ui, opts)
316 def d():
317 def d():
317 len(repo[x].files())
318 len(repo[x].files())
318 timer(d)
319 timer(d)
319 fm.end()
320 fm.end()
320
321
321 @command('perfrawfiles', formatteropts)
322 @command('perfrawfiles', formatteropts)
322 def perfrawfiles(ui, repo, x, **opts):
323 def perfrawfiles(ui, repo, x, **opts):
323 x = int(x)
324 x = int(x)
324 timer, fm = gettimer(ui, opts)
325 timer, fm = gettimer(ui, opts)
325 cl = repo.changelog
326 cl = repo.changelog
326 def d():
327 def d():
327 len(cl.read(x)[3])
328 len(cl.read(x)[3])
328 timer(d)
329 timer(d)
329 fm.end()
330 fm.end()
330
331
331 @command('perflookup', formatteropts)
332 @command('perflookup', formatteropts)
332 def perflookup(ui, repo, rev, **opts):
333 def perflookup(ui, repo, rev, **opts):
333 timer, fm = gettimer(ui, opts)
334 timer, fm = gettimer(ui, opts)
334 timer(lambda: len(repo.lookup(rev)))
335 timer(lambda: len(repo.lookup(rev)))
335 fm.end()
336 fm.end()
336
337
337 @command('perfrevrange', formatteropts)
338 @command('perfrevrange', formatteropts)
338 def perfrevrange(ui, repo, *specs, **opts):
339 def perfrevrange(ui, repo, *specs, **opts):
339 timer, fm = gettimer(ui, opts)
340 timer, fm = gettimer(ui, opts)
340 revrange = scmutil.revrange
341 revrange = scmutil.revrange
341 timer(lambda: len(revrange(repo, specs)))
342 timer(lambda: len(revrange(repo, specs)))
342 fm.end()
343 fm.end()
343
344
344 @command('perfnodelookup', formatteropts)
345 @command('perfnodelookup', formatteropts)
345 def perfnodelookup(ui, repo, rev, **opts):
346 def perfnodelookup(ui, repo, rev, **opts):
346 timer, fm = gettimer(ui, opts)
347 timer, fm = gettimer(ui, opts)
347 import mercurial.revlog
348 import mercurial.revlog
348 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
349 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
349 n = repo[rev].node()
350 n = repo[rev].node()
350 cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
351 cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
351 def d():
352 def d():
352 cl.rev(n)
353 cl.rev(n)
353 clearcaches(cl)
354 clearcaches(cl)
354 timer(d)
355 timer(d)
355 fm.end()
356 fm.end()
356
357
357 @command('perflog',
358 @command('perflog',
358 [('', 'rename', False, 'ask log to follow renames')] + formatteropts)
359 [('', 'rename', False, 'ask log to follow renames')] + formatteropts)
359 def perflog(ui, repo, **opts):
360 def perflog(ui, repo, **opts):
360 timer, fm = gettimer(ui, opts)
361 timer, fm = gettimer(ui, opts)
361 ui.pushbuffer()
362 ui.pushbuffer()
362 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
363 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
363 copies=opts.get('rename')))
364 copies=opts.get('rename')))
364 ui.popbuffer()
365 ui.popbuffer()
365 fm.end()
366 fm.end()
366
367
367 @command('perfmoonwalk', formatteropts)
368 @command('perfmoonwalk', formatteropts)
368 def perfmoonwalk(ui, repo, **opts):
369 def perfmoonwalk(ui, repo, **opts):
369 """benchmark walking the changelog backwards
370 """benchmark walking the changelog backwards
370
371
371 This also loads the changelog data for each revision in the changelog.
372 This also loads the changelog data for each revision in the changelog.
372 """
373 """
373 timer, fm = gettimer(ui, opts)
374 timer, fm = gettimer(ui, opts)
374 def moonwalk():
375 def moonwalk():
375 for i in xrange(len(repo), -1, -1):
376 for i in xrange(len(repo), -1, -1):
376 ctx = repo[i]
377 ctx = repo[i]
377 ctx.branch() # read changelog data (in addition to the index)
378 ctx.branch() # read changelog data (in addition to the index)
378 timer(moonwalk)
379 timer(moonwalk)
379 fm.end()
380 fm.end()
380
381
381 @command('perftemplating', formatteropts)
382 @command('perftemplating', formatteropts)
382 def perftemplating(ui, repo, **opts):
383 def perftemplating(ui, repo, **opts):
383 timer, fm = gettimer(ui, opts)
384 timer, fm = gettimer(ui, opts)
384 ui.pushbuffer()
385 ui.pushbuffer()
385 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
386 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
386 template='{date|shortdate} [{rev}:{node|short}]'
387 template='{date|shortdate} [{rev}:{node|short}]'
387 ' {author|person}: {desc|firstline}\n'))
388 ' {author|person}: {desc|firstline}\n'))
388 ui.popbuffer()
389 ui.popbuffer()
389 fm.end()
390 fm.end()
390
391
391 @command('perfcca', formatteropts)
392 @command('perfcca', formatteropts)
392 def perfcca(ui, repo, **opts):
393 def perfcca(ui, repo, **opts):
393 timer, fm = gettimer(ui, opts)
394 timer, fm = gettimer(ui, opts)
394 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
395 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
395 fm.end()
396 fm.end()
396
397
397 @command('perffncacheload', formatteropts)
398 @command('perffncacheload', formatteropts)
398 def perffncacheload(ui, repo, **opts):
399 def perffncacheload(ui, repo, **opts):
399 timer, fm = gettimer(ui, opts)
400 timer, fm = gettimer(ui, opts)
400 s = repo.store
401 s = repo.store
401 def d():
402 def d():
402 s.fncache._load()
403 s.fncache._load()
403 timer(d)
404 timer(d)
404 fm.end()
405 fm.end()
405
406
406 @command('perffncachewrite', formatteropts)
407 @command('perffncachewrite', formatteropts)
407 def perffncachewrite(ui, repo, **opts):
408 def perffncachewrite(ui, repo, **opts):
408 timer, fm = gettimer(ui, opts)
409 timer, fm = gettimer(ui, opts)
409 s = repo.store
410 s = repo.store
410 s.fncache._load()
411 s.fncache._load()
411 lock = repo.lock()
412 lock = repo.lock()
412 tr = repo.transaction('perffncachewrite')
413 tr = repo.transaction('perffncachewrite')
413 def d():
414 def d():
414 s.fncache._dirty = True
415 s.fncache._dirty = True
415 s.fncache.write(tr)
416 s.fncache.write(tr)
416 timer(d)
417 timer(d)
417 lock.release()
418 lock.release()
418 fm.end()
419 fm.end()
419
420
420 @command('perffncacheencode', formatteropts)
421 @command('perffncacheencode', formatteropts)
421 def perffncacheencode(ui, repo, **opts):
422 def perffncacheencode(ui, repo, **opts):
422 timer, fm = gettimer(ui, opts)
423 timer, fm = gettimer(ui, opts)
423 s = repo.store
424 s = repo.store
424 s.fncache._load()
425 s.fncache._load()
425 def d():
426 def d():
426 for p in s.fncache.entries:
427 for p in s.fncache.entries:
427 s.encode(p)
428 s.encode(p)
428 timer(d)
429 timer(d)
429 fm.end()
430 fm.end()
430
431
431 @command('perfdiffwd', formatteropts)
432 @command('perfdiffwd', formatteropts)
432 def perfdiffwd(ui, repo, **opts):
433 def perfdiffwd(ui, repo, **opts):
433 """Profile diff of working directory changes"""
434 """Profile diff of working directory changes"""
434 timer, fm = gettimer(ui, opts)
435 timer, fm = gettimer(ui, opts)
435 options = {
436 options = {
436 'w': 'ignore_all_space',
437 'w': 'ignore_all_space',
437 'b': 'ignore_space_change',
438 'b': 'ignore_space_change',
438 'B': 'ignore_blank_lines',
439 'B': 'ignore_blank_lines',
439 }
440 }
440
441
441 for diffopt in ('', 'w', 'b', 'B', 'wB'):
442 for diffopt in ('', 'w', 'b', 'B', 'wB'):
442 opts = dict((options[c], '1') for c in diffopt)
443 opts = dict((options[c], '1') for c in diffopt)
443 def d():
444 def d():
444 ui.pushbuffer()
445 ui.pushbuffer()
445 commands.diff(ui, repo, **opts)
446 commands.diff(ui, repo, **opts)
446 ui.popbuffer()
447 ui.popbuffer()
447 title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none')
448 title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none')
448 timer(d, title)
449 timer(d, title)
449 fm.end()
450 fm.end()
450
451
451 @command('perfrevlog',
452 @command('perfrevlog',
452 [('d', 'dist', 100, 'distance between the revisions')] + formatteropts,
453 [('d', 'dist', 100, 'distance between the revisions')] + formatteropts,
453 "[INDEXFILE]")
454 "[INDEXFILE]")
454 def perfrevlog(ui, repo, file_, **opts):
455 def perfrevlog(ui, repo, file_, **opts):
455 timer, fm = gettimer(ui, opts)
456 timer, fm = gettimer(ui, opts)
456 from mercurial import revlog
457 from mercurial import revlog
457 dist = opts['dist']
458 dist = opts['dist']
458 def d():
459 def d():
459 r = revlog.revlog(lambda fn: open(fn, 'rb'), file_)
460 r = revlog.revlog(lambda fn: open(fn, 'rb'), file_)
460 for x in xrange(0, len(r), dist):
461 for x in xrange(0, len(r), dist):
461 r.revision(r.node(x))
462 r.revision(r.node(x))
462
463
463 timer(d)
464 timer(d)
464 fm.end()
465 fm.end()
465
466
466 @command('perfrevset',
467 @command('perfrevset',
467 [('C', 'clear', False, 'clear volatile cache between each call.'),
468 [('C', 'clear', False, 'clear volatile cache between each call.'),
468 ('', 'contexts', False, 'obtain changectx for each revision')]
469 ('', 'contexts', False, 'obtain changectx for each revision')]
469 + formatteropts, "REVSET")
470 + formatteropts, "REVSET")
470 def perfrevset(ui, repo, expr, clear=False, contexts=False, **opts):
471 def perfrevset(ui, repo, expr, clear=False, contexts=False, **opts):
471 """benchmark the execution time of a revset
472 """benchmark the execution time of a revset
472
473
473 Use the --clean option if need to evaluate the impact of build volatile
474 Use the --clean option if need to evaluate the impact of build volatile
474 revisions set cache on the revset execution. Volatile cache hold filtered
475 revisions set cache on the revset execution. Volatile cache hold filtered
475 and obsolete related cache."""
476 and obsolete related cache."""
476 timer, fm = gettimer(ui, opts)
477 timer, fm = gettimer(ui, opts)
477 def d():
478 def d():
478 if clear:
479 if clear:
479 repo.invalidatevolatilesets()
480 repo.invalidatevolatilesets()
480 if contexts:
481 if contexts:
481 for ctx in repo.set(expr): pass
482 for ctx in repo.set(expr): pass
482 else:
483 else:
483 for r in repo.revs(expr): pass
484 for r in repo.revs(expr): pass
484 timer(d)
485 timer(d)
485 fm.end()
486 fm.end()
486
487
487 @command('perfvolatilesets', formatteropts)
488 @command('perfvolatilesets', formatteropts)
488 def perfvolatilesets(ui, repo, *names, **opts):
489 def perfvolatilesets(ui, repo, *names, **opts):
489 """benchmark the computation of various volatile set
490 """benchmark the computation of various volatile set
490
491
491 Volatile set computes element related to filtering and obsolescence."""
492 Volatile set computes element related to filtering and obsolescence."""
492 timer, fm = gettimer(ui, opts)
493 timer, fm = gettimer(ui, opts)
493 repo = repo.unfiltered()
494 repo = repo.unfiltered()
494
495
495 def getobs(name):
496 def getobs(name):
496 def d():
497 def d():
497 repo.invalidatevolatilesets()
498 repo.invalidatevolatilesets()
498 obsolete.getrevs(repo, name)
499 obsolete.getrevs(repo, name)
499 return d
500 return d
500
501
501 allobs = sorted(obsolete.cachefuncs)
502 allobs = sorted(obsolete.cachefuncs)
502 if names:
503 if names:
503 allobs = [n for n in allobs if n in names]
504 allobs = [n for n in allobs if n in names]
504
505
505 for name in allobs:
506 for name in allobs:
506 timer(getobs(name), title=name)
507 timer(getobs(name), title=name)
507
508
508 def getfiltered(name):
509 def getfiltered(name):
509 def d():
510 def d():
510 repo.invalidatevolatilesets()
511 repo.invalidatevolatilesets()
511 repoview.filterrevs(repo, name)
512 repoview.filterrevs(repo, name)
512 return d
513 return d
513
514
514 allfilter = sorted(repoview.filtertable)
515 allfilter = sorted(repoview.filtertable)
515 if names:
516 if names:
516 allfilter = [n for n in allfilter if n in names]
517 allfilter = [n for n in allfilter if n in names]
517
518
518 for name in allfilter:
519 for name in allfilter:
519 timer(getfiltered(name), title=name)
520 timer(getfiltered(name), title=name)
520 fm.end()
521 fm.end()
521
522
522 @command('perfbranchmap',
523 @command('perfbranchmap',
523 [('f', 'full', False,
524 [('f', 'full', False,
524 'Includes build time of subset'),
525 'Includes build time of subset'),
525 ] + formatteropts)
526 ] + formatteropts)
526 def perfbranchmap(ui, repo, full=False, **opts):
527 def perfbranchmap(ui, repo, full=False, **opts):
527 """benchmark the update of a branchmap
528 """benchmark the update of a branchmap
528
529
529 This benchmarks the full repo.branchmap() call with read and write disabled
530 This benchmarks the full repo.branchmap() call with read and write disabled
530 """
531 """
531 timer, fm = gettimer(ui, opts)
532 timer, fm = gettimer(ui, opts)
532 def getbranchmap(filtername):
533 def getbranchmap(filtername):
533 """generate a benchmark function for the filtername"""
534 """generate a benchmark function for the filtername"""
534 if filtername is None:
535 if filtername is None:
535 view = repo
536 view = repo
536 else:
537 else:
537 view = repo.filtered(filtername)
538 view = repo.filtered(filtername)
538 def d():
539 def d():
539 if full:
540 if full:
540 view._branchcaches.clear()
541 view._branchcaches.clear()
541 else:
542 else:
542 view._branchcaches.pop(filtername, None)
543 view._branchcaches.pop(filtername, None)
543 view.branchmap()
544 view.branchmap()
544 return d
545 return d
545 # add filter in smaller subset to bigger subset
546 # add filter in smaller subset to bigger subset
546 possiblefilters = set(repoview.filtertable)
547 possiblefilters = set(repoview.filtertable)
547 allfilters = []
548 allfilters = []
548 while possiblefilters:
549 while possiblefilters:
549 for name in possiblefilters:
550 for name in possiblefilters:
550 subset = branchmap.subsettable.get(name)
551 subset = branchmap.subsettable.get(name)
551 if subset not in possiblefilters:
552 if subset not in possiblefilters:
552 break
553 break
553 else:
554 else:
554 assert False, 'subset cycle %s!' % possiblefilters
555 assert False, 'subset cycle %s!' % possiblefilters
555 allfilters.append(name)
556 allfilters.append(name)
556 possiblefilters.remove(name)
557 possiblefilters.remove(name)
557
558
558 # warm the cache
559 # warm the cache
559 if not full:
560 if not full:
560 for name in allfilters:
561 for name in allfilters:
561 repo.filtered(name).branchmap()
562 repo.filtered(name).branchmap()
562 # add unfiltered
563 # add unfiltered
563 allfilters.append(None)
564 allfilters.append(None)
564 oldread = branchmap.read
565 oldread = branchmap.read
565 oldwrite = branchmap.branchcache.write
566 oldwrite = branchmap.branchcache.write
566 try:
567 try:
567 branchmap.read = lambda repo: None
568 branchmap.read = lambda repo: None
568 branchmap.write = lambda repo: None
569 branchmap.write = lambda repo: None
569 for name in allfilters:
570 for name in allfilters:
570 timer(getbranchmap(name), title=str(name))
571 timer(getbranchmap(name), title=str(name))
571 finally:
572 finally:
572 branchmap.read = oldread
573 branchmap.read = oldread
573 branchmap.branchcache.write = oldwrite
574 branchmap.branchcache.write = oldwrite
574 fm.end()
575 fm.end()
575
576
576 @command('perfloadmarkers')
577 @command('perfloadmarkers')
577 def perfloadmarkers(ui, repo):
578 def perfloadmarkers(ui, repo):
578 """benchmark the time to parse the on-disk markers for a repo
579 """benchmark the time to parse the on-disk markers for a repo
579
580
580 Result is the number of markers in the repo."""
581 Result is the number of markers in the repo."""
581 timer, fm = gettimer(ui)
582 timer, fm = gettimer(ui)
582 timer(lambda: len(obsolete.obsstore(repo.svfs)))
583 timer(lambda: len(obsolete.obsstore(repo.svfs)))
583 fm.end()
584 fm.end()
General Comments 0
You need to be logged in to leave comments. Login now