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