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