##// END OF EJS Templates
perf: use standard arguments for perfrevlog...
Gregory Szorc -
r27492:ac549d7f default
parent child Browse files
Show More
@@ -1,776 +1,780
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, revlog
5 from mercurial import repoview, branchmap, merge, copies, error, revlog
6 from mercurial import mdiff
6 from mercurial import mdiff
7 import time, os, sys
7 import time, os, sys
8 import random
8 import random
9 import functools
9 import functools
10
10
11 formatteropts = commands.formatteropts
11 formatteropts = commands.formatteropts
12 revlogopts = commands.debugrevlogopts
12 revlogopts = commands.debugrevlogopts
13
13
14 cmdtable = {}
14 cmdtable = {}
15 command = cmdutil.command(cmdtable)
15 command = cmdutil.command(cmdtable)
16
16
17 def getlen(ui):
17 def getlen(ui):
18 if ui.configbool("perf", "stub"):
18 if ui.configbool("perf", "stub"):
19 return lambda x: 1
19 return lambda x: 1
20 return len
20 return len
21
21
22 def gettimer(ui, opts=None):
22 def gettimer(ui, opts=None):
23 """return a timer function and formatter: (timer, formatter)
23 """return a timer function and formatter: (timer, formatter)
24
24
25 This function exists to gather the creation of formatter in a single
25 This function exists to gather the creation of formatter in a single
26 place instead of duplicating it in all performance commands."""
26 place instead of duplicating it in all performance commands."""
27
27
28 # enforce an idle period before execution to counteract power management
28 # enforce an idle period before execution to counteract power management
29 # experimental config: perf.presleep
29 # experimental config: perf.presleep
30 time.sleep(ui.configint("perf", "presleep", 1))
30 time.sleep(ui.configint("perf", "presleep", 1))
31
31
32 if opts is None:
32 if opts is None:
33 opts = {}
33 opts = {}
34 # redirect all to stderr
34 # redirect all to stderr
35 ui = ui.copy()
35 ui = ui.copy()
36 ui.fout = ui.ferr
36 ui.fout = ui.ferr
37 # get a formatter
37 # get a formatter
38 fm = ui.formatter('perf', opts)
38 fm = ui.formatter('perf', opts)
39 # stub function, runs code only once instead of in a loop
39 # stub function, runs code only once instead of in a loop
40 # experimental config: perf.stub
40 # experimental config: perf.stub
41 if ui.configbool("perf", "stub"):
41 if ui.configbool("perf", "stub"):
42 return functools.partial(stub_timer, fm), fm
42 return functools.partial(stub_timer, fm), fm
43 return functools.partial(_timer, fm), fm
43 return functools.partial(_timer, fm), fm
44
44
45 def stub_timer(fm, func, title=None):
45 def stub_timer(fm, func, title=None):
46 func()
46 func()
47
47
48 def _timer(fm, func, title=None):
48 def _timer(fm, func, title=None):
49 results = []
49 results = []
50 begin = time.time()
50 begin = time.time()
51 count = 0
51 count = 0
52 while True:
52 while True:
53 ostart = os.times()
53 ostart = os.times()
54 cstart = time.time()
54 cstart = time.time()
55 r = func()
55 r = func()
56 cstop = time.time()
56 cstop = time.time()
57 ostop = os.times()
57 ostop = os.times()
58 count += 1
58 count += 1
59 a, b = ostart, ostop
59 a, b = ostart, ostop
60 results.append((cstop - cstart, b[0] - a[0], b[1]-a[1]))
60 results.append((cstop - cstart, b[0] - a[0], b[1]-a[1]))
61 if cstop - begin > 3 and count >= 100:
61 if cstop - begin > 3 and count >= 100:
62 break
62 break
63 if cstop - begin > 10 and count >= 3:
63 if cstop - begin > 10 and count >= 3:
64 break
64 break
65
65
66 fm.startitem()
66 fm.startitem()
67
67
68 if title:
68 if title:
69 fm.write('title', '! %s\n', title)
69 fm.write('title', '! %s\n', title)
70 if r:
70 if r:
71 fm.write('result', '! result: %s\n', r)
71 fm.write('result', '! result: %s\n', r)
72 m = min(results)
72 m = min(results)
73 fm.plain('!')
73 fm.plain('!')
74 fm.write('wall', ' wall %f', m[0])
74 fm.write('wall', ' wall %f', m[0])
75 fm.write('comb', ' comb %f', m[1] + m[2])
75 fm.write('comb', ' comb %f', m[1] + m[2])
76 fm.write('user', ' user %f', m[1])
76 fm.write('user', ' user %f', m[1])
77 fm.write('sys', ' sys %f', m[2])
77 fm.write('sys', ' sys %f', m[2])
78 fm.write('count', ' (best of %d)', count)
78 fm.write('count', ' (best of %d)', count)
79 fm.plain('\n')
79 fm.plain('\n')
80
80
81 @command('perfwalk', formatteropts)
81 @command('perfwalk', formatteropts)
82 def perfwalk(ui, repo, *pats, **opts):
82 def perfwalk(ui, repo, *pats, **opts):
83 timer, fm = gettimer(ui, opts)
83 timer, fm = gettimer(ui, opts)
84 try:
84 try:
85 m = scmutil.match(repo[None], pats, {})
85 m = scmutil.match(repo[None], pats, {})
86 timer(lambda: len(list(repo.dirstate.walk(m, [], True, False))))
86 timer(lambda: len(list(repo.dirstate.walk(m, [], True, False))))
87 except Exception:
87 except Exception:
88 try:
88 try:
89 m = scmutil.match(repo[None], pats, {})
89 m = scmutil.match(repo[None], pats, {})
90 timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)]))
90 timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)]))
91 except Exception:
91 except Exception:
92 timer(lambda: len(list(cmdutil.walk(repo, pats, {}))))
92 timer(lambda: len(list(cmdutil.walk(repo, pats, {}))))
93 fm.end()
93 fm.end()
94
94
95 @command('perfannotate', formatteropts)
95 @command('perfannotate', formatteropts)
96 def perfannotate(ui, repo, f, **opts):
96 def perfannotate(ui, repo, f, **opts):
97 timer, fm = gettimer(ui, opts)
97 timer, fm = gettimer(ui, opts)
98 fc = repo['.'][f]
98 fc = repo['.'][f]
99 timer(lambda: len(fc.annotate(True)))
99 timer(lambda: len(fc.annotate(True)))
100 fm.end()
100 fm.end()
101
101
102 @command('perfstatus',
102 @command('perfstatus',
103 [('u', 'unknown', False,
103 [('u', 'unknown', False,
104 'ask status to look for unknown files')] + formatteropts)
104 'ask status to look for unknown files')] + formatteropts)
105 def perfstatus(ui, repo, **opts):
105 def perfstatus(ui, repo, **opts):
106 #m = match.always(repo.root, repo.getcwd())
106 #m = match.always(repo.root, repo.getcwd())
107 #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False,
107 #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False,
108 # False))))
108 # False))))
109 timer, fm = gettimer(ui, opts)
109 timer, fm = gettimer(ui, opts)
110 timer(lambda: sum(map(len, repo.status(unknown=opts['unknown']))))
110 timer(lambda: sum(map(len, repo.status(unknown=opts['unknown']))))
111 fm.end()
111 fm.end()
112
112
113 @command('perfaddremove', formatteropts)
113 @command('perfaddremove', formatteropts)
114 def perfaddremove(ui, repo, **opts):
114 def perfaddremove(ui, repo, **opts):
115 timer, fm = gettimer(ui, opts)
115 timer, fm = gettimer(ui, opts)
116 try:
116 try:
117 oldquiet = repo.ui.quiet
117 oldquiet = repo.ui.quiet
118 repo.ui.quiet = True
118 repo.ui.quiet = True
119 matcher = scmutil.match(repo[None])
119 matcher = scmutil.match(repo[None])
120 timer(lambda: scmutil.addremove(repo, matcher, "", dry_run=True))
120 timer(lambda: scmutil.addremove(repo, matcher, "", dry_run=True))
121 finally:
121 finally:
122 repo.ui.quiet = oldquiet
122 repo.ui.quiet = oldquiet
123 fm.end()
123 fm.end()
124
124
125 def clearcaches(cl):
125 def clearcaches(cl):
126 # behave somewhat consistently across internal API changes
126 # behave somewhat consistently across internal API changes
127 if util.safehasattr(cl, 'clearcaches'):
127 if util.safehasattr(cl, 'clearcaches'):
128 cl.clearcaches()
128 cl.clearcaches()
129 elif util.safehasattr(cl, '_nodecache'):
129 elif util.safehasattr(cl, '_nodecache'):
130 from mercurial.node import nullid, nullrev
130 from mercurial.node import nullid, nullrev
131 cl._nodecache = {nullid: nullrev}
131 cl._nodecache = {nullid: nullrev}
132 cl._nodepos = None
132 cl._nodepos = None
133
133
134 @command('perfheads', formatteropts)
134 @command('perfheads', formatteropts)
135 def perfheads(ui, repo, **opts):
135 def perfheads(ui, repo, **opts):
136 timer, fm = gettimer(ui, opts)
136 timer, fm = gettimer(ui, opts)
137 cl = repo.changelog
137 cl = repo.changelog
138 def d():
138 def d():
139 len(cl.headrevs())
139 len(cl.headrevs())
140 clearcaches(cl)
140 clearcaches(cl)
141 timer(d)
141 timer(d)
142 fm.end()
142 fm.end()
143
143
144 @command('perftags', formatteropts)
144 @command('perftags', formatteropts)
145 def perftags(ui, repo, **opts):
145 def perftags(ui, repo, **opts):
146 import mercurial.changelog
146 import mercurial.changelog
147 import mercurial.manifest
147 import mercurial.manifest
148 timer, fm = gettimer(ui, opts)
148 timer, fm = gettimer(ui, opts)
149 def t():
149 def t():
150 repo.changelog = mercurial.changelog.changelog(repo.svfs)
150 repo.changelog = mercurial.changelog.changelog(repo.svfs)
151 repo.manifest = mercurial.manifest.manifest(repo.svfs)
151 repo.manifest = mercurial.manifest.manifest(repo.svfs)
152 repo._tags = None
152 repo._tags = None
153 return len(repo.tags())
153 return len(repo.tags())
154 timer(t)
154 timer(t)
155 fm.end()
155 fm.end()
156
156
157 @command('perfancestors', formatteropts)
157 @command('perfancestors', formatteropts)
158 def perfancestors(ui, repo, **opts):
158 def perfancestors(ui, repo, **opts):
159 timer, fm = gettimer(ui, opts)
159 timer, fm = gettimer(ui, opts)
160 heads = repo.changelog.headrevs()
160 heads = repo.changelog.headrevs()
161 def d():
161 def d():
162 for a in repo.changelog.ancestors(heads):
162 for a in repo.changelog.ancestors(heads):
163 pass
163 pass
164 timer(d)
164 timer(d)
165 fm.end()
165 fm.end()
166
166
167 @command('perfancestorset', formatteropts)
167 @command('perfancestorset', formatteropts)
168 def perfancestorset(ui, repo, revset, **opts):
168 def perfancestorset(ui, repo, revset, **opts):
169 timer, fm = gettimer(ui, opts)
169 timer, fm = gettimer(ui, opts)
170 revs = repo.revs(revset)
170 revs = repo.revs(revset)
171 heads = repo.changelog.headrevs()
171 heads = repo.changelog.headrevs()
172 def d():
172 def d():
173 s = repo.changelog.ancestors(heads)
173 s = repo.changelog.ancestors(heads)
174 for rev in revs:
174 for rev in revs:
175 rev in s
175 rev in s
176 timer(d)
176 timer(d)
177 fm.end()
177 fm.end()
178
178
179 @command('perfdirs', formatteropts)
179 @command('perfdirs', formatteropts)
180 def perfdirs(ui, repo, **opts):
180 def perfdirs(ui, repo, **opts):
181 timer, fm = gettimer(ui, opts)
181 timer, fm = gettimer(ui, opts)
182 dirstate = repo.dirstate
182 dirstate = repo.dirstate
183 'a' in dirstate
183 'a' in dirstate
184 def d():
184 def d():
185 dirstate.dirs()
185 dirstate.dirs()
186 del dirstate._dirs
186 del dirstate._dirs
187 timer(d)
187 timer(d)
188 fm.end()
188 fm.end()
189
189
190 @command('perfdirstate', formatteropts)
190 @command('perfdirstate', formatteropts)
191 def perfdirstate(ui, repo, **opts):
191 def perfdirstate(ui, repo, **opts):
192 timer, fm = gettimer(ui, opts)
192 timer, fm = gettimer(ui, opts)
193 "a" in repo.dirstate
193 "a" in repo.dirstate
194 def d():
194 def d():
195 repo.dirstate.invalidate()
195 repo.dirstate.invalidate()
196 "a" in repo.dirstate
196 "a" in repo.dirstate
197 timer(d)
197 timer(d)
198 fm.end()
198 fm.end()
199
199
200 @command('perfdirstatedirs', formatteropts)
200 @command('perfdirstatedirs', formatteropts)
201 def perfdirstatedirs(ui, repo, **opts):
201 def perfdirstatedirs(ui, repo, **opts):
202 timer, fm = gettimer(ui, opts)
202 timer, fm = gettimer(ui, opts)
203 "a" in repo.dirstate
203 "a" in repo.dirstate
204 def d():
204 def d():
205 "a" in repo.dirstate._dirs
205 "a" in repo.dirstate._dirs
206 del repo.dirstate._dirs
206 del repo.dirstate._dirs
207 timer(d)
207 timer(d)
208 fm.end()
208 fm.end()
209
209
210 @command('perfdirstatefoldmap', formatteropts)
210 @command('perfdirstatefoldmap', formatteropts)
211 def perfdirstatefoldmap(ui, repo, **opts):
211 def perfdirstatefoldmap(ui, repo, **opts):
212 timer, fm = gettimer(ui, opts)
212 timer, fm = gettimer(ui, opts)
213 dirstate = repo.dirstate
213 dirstate = repo.dirstate
214 'a' in dirstate
214 'a' in dirstate
215 def d():
215 def d():
216 dirstate._filefoldmap.get('a')
216 dirstate._filefoldmap.get('a')
217 del dirstate._filefoldmap
217 del dirstate._filefoldmap
218 timer(d)
218 timer(d)
219 fm.end()
219 fm.end()
220
220
221 @command('perfdirfoldmap', formatteropts)
221 @command('perfdirfoldmap', formatteropts)
222 def perfdirfoldmap(ui, repo, **opts):
222 def perfdirfoldmap(ui, repo, **opts):
223 timer, fm = gettimer(ui, opts)
223 timer, fm = gettimer(ui, opts)
224 dirstate = repo.dirstate
224 dirstate = repo.dirstate
225 'a' in dirstate
225 'a' in dirstate
226 def d():
226 def d():
227 dirstate._dirfoldmap.get('a')
227 dirstate._dirfoldmap.get('a')
228 del dirstate._dirfoldmap
228 del dirstate._dirfoldmap
229 del dirstate._dirs
229 del dirstate._dirs
230 timer(d)
230 timer(d)
231 fm.end()
231 fm.end()
232
232
233 @command('perfdirstatewrite', formatteropts)
233 @command('perfdirstatewrite', formatteropts)
234 def perfdirstatewrite(ui, repo, **opts):
234 def perfdirstatewrite(ui, repo, **opts):
235 timer, fm = gettimer(ui, opts)
235 timer, fm = gettimer(ui, opts)
236 ds = repo.dirstate
236 ds = repo.dirstate
237 "a" in ds
237 "a" in ds
238 def d():
238 def d():
239 ds._dirty = True
239 ds._dirty = True
240 ds.write(repo.currenttransaction())
240 ds.write(repo.currenttransaction())
241 timer(d)
241 timer(d)
242 fm.end()
242 fm.end()
243
243
244 @command('perfmergecalculate',
244 @command('perfmergecalculate',
245 [('r', 'rev', '.', 'rev to merge against')] + formatteropts)
245 [('r', 'rev', '.', 'rev to merge against')] + formatteropts)
246 def perfmergecalculate(ui, repo, rev, **opts):
246 def perfmergecalculate(ui, repo, rev, **opts):
247 timer, fm = gettimer(ui, opts)
247 timer, fm = gettimer(ui, opts)
248 wctx = repo[None]
248 wctx = repo[None]
249 rctx = scmutil.revsingle(repo, rev, rev)
249 rctx = scmutil.revsingle(repo, rev, rev)
250 ancestor = wctx.ancestor(rctx)
250 ancestor = wctx.ancestor(rctx)
251 # we don't want working dir files to be stat'd in the benchmark, so prime
251 # we don't want working dir files to be stat'd in the benchmark, so prime
252 # that cache
252 # that cache
253 wctx.dirty()
253 wctx.dirty()
254 def d():
254 def d():
255 # acceptremote is True because we don't want prompts in the middle of
255 # acceptremote is True because we don't want prompts in the middle of
256 # our benchmark
256 # our benchmark
257 merge.calculateupdates(repo, wctx, rctx, [ancestor], False, False,
257 merge.calculateupdates(repo, wctx, rctx, [ancestor], False, False,
258 acceptremote=True, followcopies=True)
258 acceptremote=True, followcopies=True)
259 timer(d)
259 timer(d)
260 fm.end()
260 fm.end()
261
261
262 @command('perfpathcopies', [], "REV REV")
262 @command('perfpathcopies', [], "REV REV")
263 def perfpathcopies(ui, repo, rev1, rev2, **opts):
263 def perfpathcopies(ui, repo, rev1, rev2, **opts):
264 timer, fm = gettimer(ui, opts)
264 timer, fm = gettimer(ui, opts)
265 ctx1 = scmutil.revsingle(repo, rev1, rev1)
265 ctx1 = scmutil.revsingle(repo, rev1, rev1)
266 ctx2 = scmutil.revsingle(repo, rev2, rev2)
266 ctx2 = scmutil.revsingle(repo, rev2, rev2)
267 def d():
267 def d():
268 copies.pathcopies(ctx1, ctx2)
268 copies.pathcopies(ctx1, ctx2)
269 timer(d)
269 timer(d)
270 fm.end()
270 fm.end()
271
271
272 @command('perfmanifest', [], 'REV')
272 @command('perfmanifest', [], 'REV')
273 def perfmanifest(ui, repo, rev, **opts):
273 def perfmanifest(ui, repo, rev, **opts):
274 timer, fm = gettimer(ui, opts)
274 timer, fm = gettimer(ui, opts)
275 ctx = scmutil.revsingle(repo, rev, rev)
275 ctx = scmutil.revsingle(repo, rev, rev)
276 t = ctx.manifestnode()
276 t = ctx.manifestnode()
277 def d():
277 def d():
278 repo.manifest.clearcaches()
278 repo.manifest.clearcaches()
279 repo.manifest.read(t)
279 repo.manifest.read(t)
280 timer(d)
280 timer(d)
281 fm.end()
281 fm.end()
282
282
283 @command('perfchangeset', formatteropts)
283 @command('perfchangeset', formatteropts)
284 def perfchangeset(ui, repo, rev, **opts):
284 def perfchangeset(ui, repo, rev, **opts):
285 timer, fm = gettimer(ui, opts)
285 timer, fm = gettimer(ui, opts)
286 n = repo[rev].node()
286 n = repo[rev].node()
287 def d():
287 def d():
288 repo.changelog.read(n)
288 repo.changelog.read(n)
289 #repo.changelog._cache = None
289 #repo.changelog._cache = None
290 timer(d)
290 timer(d)
291 fm.end()
291 fm.end()
292
292
293 @command('perfindex', formatteropts)
293 @command('perfindex', formatteropts)
294 def perfindex(ui, repo, **opts):
294 def perfindex(ui, repo, **opts):
295 import mercurial.revlog
295 import mercurial.revlog
296 timer, fm = gettimer(ui, opts)
296 timer, fm = gettimer(ui, opts)
297 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
297 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
298 n = repo["tip"].node()
298 n = repo["tip"].node()
299 def d():
299 def d():
300 cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
300 cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
301 cl.rev(n)
301 cl.rev(n)
302 timer(d)
302 timer(d)
303 fm.end()
303 fm.end()
304
304
305 @command('perfstartup', formatteropts)
305 @command('perfstartup', formatteropts)
306 def perfstartup(ui, repo, **opts):
306 def perfstartup(ui, repo, **opts):
307 timer, fm = gettimer(ui, opts)
307 timer, fm = gettimer(ui, opts)
308 cmd = sys.argv[0]
308 cmd = sys.argv[0]
309 def d():
309 def d():
310 if os.name != 'nt':
310 if os.name != 'nt':
311 os.system("HGRCPATH= %s version -q > /dev/null" % cmd)
311 os.system("HGRCPATH= %s version -q > /dev/null" % cmd)
312 else:
312 else:
313 os.environ['HGRCPATH'] = ''
313 os.environ['HGRCPATH'] = ''
314 os.system("%s version -q > NUL" % cmd)
314 os.system("%s version -q > NUL" % cmd)
315 timer(d)
315 timer(d)
316 fm.end()
316 fm.end()
317
317
318 @command('perfparents', formatteropts)
318 @command('perfparents', formatteropts)
319 def perfparents(ui, repo, **opts):
319 def perfparents(ui, repo, **opts):
320 timer, fm = gettimer(ui, opts)
320 timer, fm = gettimer(ui, opts)
321 # control the number of commits perfparents iterates over
321 # control the number of commits perfparents iterates over
322 # experimental config: perf.parentscount
322 # experimental config: perf.parentscount
323 count = ui.configint("perf", "parentscount", 1000)
323 count = ui.configint("perf", "parentscount", 1000)
324 if len(repo.changelog) < count:
324 if len(repo.changelog) < count:
325 raise error.Abort("repo needs %d commits for this test" % count)
325 raise error.Abort("repo needs %d commits for this test" % count)
326 repo = repo.unfiltered()
326 repo = repo.unfiltered()
327 nl = [repo.changelog.node(i) for i in xrange(count)]
327 nl = [repo.changelog.node(i) for i in xrange(count)]
328 def d():
328 def d():
329 for n in nl:
329 for n in nl:
330 repo.changelog.parents(n)
330 repo.changelog.parents(n)
331 timer(d)
331 timer(d)
332 fm.end()
332 fm.end()
333
333
334 @command('perfctxfiles', formatteropts)
334 @command('perfctxfiles', formatteropts)
335 def perfctxfiles(ui, repo, x, **opts):
335 def perfctxfiles(ui, repo, x, **opts):
336 x = int(x)
336 x = int(x)
337 timer, fm = gettimer(ui, opts)
337 timer, fm = gettimer(ui, opts)
338 def d():
338 def d():
339 len(repo[x].files())
339 len(repo[x].files())
340 timer(d)
340 timer(d)
341 fm.end()
341 fm.end()
342
342
343 @command('perfrawfiles', formatteropts)
343 @command('perfrawfiles', formatteropts)
344 def perfrawfiles(ui, repo, x, **opts):
344 def perfrawfiles(ui, repo, x, **opts):
345 x = int(x)
345 x = int(x)
346 timer, fm = gettimer(ui, opts)
346 timer, fm = gettimer(ui, opts)
347 cl = repo.changelog
347 cl = repo.changelog
348 def d():
348 def d():
349 len(cl.read(x)[3])
349 len(cl.read(x)[3])
350 timer(d)
350 timer(d)
351 fm.end()
351 fm.end()
352
352
353 @command('perflookup', formatteropts)
353 @command('perflookup', formatteropts)
354 def perflookup(ui, repo, rev, **opts):
354 def perflookup(ui, repo, rev, **opts):
355 timer, fm = gettimer(ui, opts)
355 timer, fm = gettimer(ui, opts)
356 timer(lambda: len(repo.lookup(rev)))
356 timer(lambda: len(repo.lookup(rev)))
357 fm.end()
357 fm.end()
358
358
359 @command('perfrevrange', formatteropts)
359 @command('perfrevrange', formatteropts)
360 def perfrevrange(ui, repo, *specs, **opts):
360 def perfrevrange(ui, repo, *specs, **opts):
361 timer, fm = gettimer(ui, opts)
361 timer, fm = gettimer(ui, opts)
362 revrange = scmutil.revrange
362 revrange = scmutil.revrange
363 timer(lambda: len(revrange(repo, specs)))
363 timer(lambda: len(revrange(repo, specs)))
364 fm.end()
364 fm.end()
365
365
366 @command('perfnodelookup', formatteropts)
366 @command('perfnodelookup', formatteropts)
367 def perfnodelookup(ui, repo, rev, **opts):
367 def perfnodelookup(ui, repo, rev, **opts):
368 timer, fm = gettimer(ui, opts)
368 timer, fm = gettimer(ui, opts)
369 import mercurial.revlog
369 import mercurial.revlog
370 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
370 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
371 n = repo[rev].node()
371 n = repo[rev].node()
372 cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
372 cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
373 def d():
373 def d():
374 cl.rev(n)
374 cl.rev(n)
375 clearcaches(cl)
375 clearcaches(cl)
376 timer(d)
376 timer(d)
377 fm.end()
377 fm.end()
378
378
379 @command('perflog',
379 @command('perflog',
380 [('', 'rename', False, 'ask log to follow renames')] + formatteropts)
380 [('', 'rename', False, 'ask log to follow renames')] + formatteropts)
381 def perflog(ui, repo, rev=None, **opts):
381 def perflog(ui, repo, rev=None, **opts):
382 if rev is None:
382 if rev is None:
383 rev=[]
383 rev=[]
384 timer, fm = gettimer(ui, opts)
384 timer, fm = gettimer(ui, opts)
385 ui.pushbuffer()
385 ui.pushbuffer()
386 timer(lambda: commands.log(ui, repo, rev=rev, date='', user='',
386 timer(lambda: commands.log(ui, repo, rev=rev, date='', user='',
387 copies=opts.get('rename')))
387 copies=opts.get('rename')))
388 ui.popbuffer()
388 ui.popbuffer()
389 fm.end()
389 fm.end()
390
390
391 @command('perfmoonwalk', formatteropts)
391 @command('perfmoonwalk', formatteropts)
392 def perfmoonwalk(ui, repo, **opts):
392 def perfmoonwalk(ui, repo, **opts):
393 """benchmark walking the changelog backwards
393 """benchmark walking the changelog backwards
394
394
395 This also loads the changelog data for each revision in the changelog.
395 This also loads the changelog data for each revision in the changelog.
396 """
396 """
397 timer, fm = gettimer(ui, opts)
397 timer, fm = gettimer(ui, opts)
398 def moonwalk():
398 def moonwalk():
399 for i in xrange(len(repo), -1, -1):
399 for i in xrange(len(repo), -1, -1):
400 ctx = repo[i]
400 ctx = repo[i]
401 ctx.branch() # read changelog data (in addition to the index)
401 ctx.branch() # read changelog data (in addition to the index)
402 timer(moonwalk)
402 timer(moonwalk)
403 fm.end()
403 fm.end()
404
404
405 @command('perftemplating', formatteropts)
405 @command('perftemplating', formatteropts)
406 def perftemplating(ui, repo, rev=None, **opts):
406 def perftemplating(ui, repo, rev=None, **opts):
407 if rev is None:
407 if rev is None:
408 rev=[]
408 rev=[]
409 timer, fm = gettimer(ui, opts)
409 timer, fm = gettimer(ui, opts)
410 ui.pushbuffer()
410 ui.pushbuffer()
411 timer(lambda: commands.log(ui, repo, rev=rev, date='', user='',
411 timer(lambda: commands.log(ui, repo, rev=rev, date='', user='',
412 template='{date|shortdate} [{rev}:{node|short}]'
412 template='{date|shortdate} [{rev}:{node|short}]'
413 ' {author|person}: {desc|firstline}\n'))
413 ' {author|person}: {desc|firstline}\n'))
414 ui.popbuffer()
414 ui.popbuffer()
415 fm.end()
415 fm.end()
416
416
417 @command('perfcca', formatteropts)
417 @command('perfcca', formatteropts)
418 def perfcca(ui, repo, **opts):
418 def perfcca(ui, repo, **opts):
419 timer, fm = gettimer(ui, opts)
419 timer, fm = gettimer(ui, opts)
420 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
420 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
421 fm.end()
421 fm.end()
422
422
423 @command('perffncacheload', formatteropts)
423 @command('perffncacheload', formatteropts)
424 def perffncacheload(ui, repo, **opts):
424 def perffncacheload(ui, repo, **opts):
425 timer, fm = gettimer(ui, opts)
425 timer, fm = gettimer(ui, opts)
426 s = repo.store
426 s = repo.store
427 def d():
427 def d():
428 s.fncache._load()
428 s.fncache._load()
429 timer(d)
429 timer(d)
430 fm.end()
430 fm.end()
431
431
432 @command('perffncachewrite', formatteropts)
432 @command('perffncachewrite', formatteropts)
433 def perffncachewrite(ui, repo, **opts):
433 def perffncachewrite(ui, repo, **opts):
434 timer, fm = gettimer(ui, opts)
434 timer, fm = gettimer(ui, opts)
435 s = repo.store
435 s = repo.store
436 s.fncache._load()
436 s.fncache._load()
437 lock = repo.lock()
437 lock = repo.lock()
438 tr = repo.transaction('perffncachewrite')
438 tr = repo.transaction('perffncachewrite')
439 def d():
439 def d():
440 s.fncache._dirty = True
440 s.fncache._dirty = True
441 s.fncache.write(tr)
441 s.fncache.write(tr)
442 timer(d)
442 timer(d)
443 lock.release()
443 lock.release()
444 fm.end()
444 fm.end()
445
445
446 @command('perffncacheencode', formatteropts)
446 @command('perffncacheencode', formatteropts)
447 def perffncacheencode(ui, repo, **opts):
447 def perffncacheencode(ui, repo, **opts):
448 timer, fm = gettimer(ui, opts)
448 timer, fm = gettimer(ui, opts)
449 s = repo.store
449 s = repo.store
450 s.fncache._load()
450 s.fncache._load()
451 def d():
451 def d():
452 for p in s.fncache.entries:
452 for p in s.fncache.entries:
453 s.encode(p)
453 s.encode(p)
454 timer(d)
454 timer(d)
455 fm.end()
455 fm.end()
456
456
457 @command('perfdiffwd', formatteropts)
457 @command('perfdiffwd', formatteropts)
458 def perfdiffwd(ui, repo, **opts):
458 def perfdiffwd(ui, repo, **opts):
459 """Profile diff of working directory changes"""
459 """Profile diff of working directory changes"""
460 timer, fm = gettimer(ui, opts)
460 timer, fm = gettimer(ui, opts)
461 options = {
461 options = {
462 'w': 'ignore_all_space',
462 'w': 'ignore_all_space',
463 'b': 'ignore_space_change',
463 'b': 'ignore_space_change',
464 'B': 'ignore_blank_lines',
464 'B': 'ignore_blank_lines',
465 }
465 }
466
466
467 for diffopt in ('', 'w', 'b', 'B', 'wB'):
467 for diffopt in ('', 'w', 'b', 'B', 'wB'):
468 opts = dict((options[c], '1') for c in diffopt)
468 opts = dict((options[c], '1') for c in diffopt)
469 def d():
469 def d():
470 ui.pushbuffer()
470 ui.pushbuffer()
471 commands.diff(ui, repo, **opts)
471 commands.diff(ui, repo, **opts)
472 ui.popbuffer()
472 ui.popbuffer()
473 title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none')
473 title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none')
474 timer(d, title)
474 timer(d, title)
475 fm.end()
475 fm.end()
476
476
477 @command('perfrevlog',
477 @command('perfrevlog', revlogopts + formatteropts +
478 [('d', 'dist', 100, 'distance between the revisions')] + formatteropts,
478 [('d', 'dist', 100, 'distance between the revisions')],
479 "[INDEXFILE]")
479 '-c|-m|FILE')
480 def perfrevlog(ui, repo, file_, **opts):
480 def perfrevlog(ui, repo, file_=None, **opts):
481 """Benchmark reading a series of revisions from a revlog.
482
483 By default, we read every ``-d/--dist`` revision from 0 to tip of
484 the specified revlog.
485 """
481 timer, fm = gettimer(ui, opts)
486 timer, fm = gettimer(ui, opts)
482 from mercurial import revlog
483 dist = opts['dist']
487 dist = opts['dist']
484 _len = getlen(ui)
488 _len = getlen(ui)
485 def d():
489 def d():
486 r = revlog.revlog(lambda fn: open(fn, 'rb'), file_)
490 r = cmdutil.openrevlog(repo, 'perfrevlog', file_, opts)
487 for x in xrange(0, _len(r), dist):
491 for x in xrange(0, _len(r), dist):
488 r.revision(r.node(x))
492 r.revision(r.node(x))
489
493
490 timer(d)
494 timer(d)
491 fm.end()
495 fm.end()
492
496
493 @command('perfrevlogrevision', revlogopts + formatteropts +
497 @command('perfrevlogrevision', revlogopts + formatteropts +
494 [('', 'cache', False, 'use caches instead of clearing')],
498 [('', 'cache', False, 'use caches instead of clearing')],
495 '-c|-m|FILE REV')
499 '-c|-m|FILE REV')
496 def perfrevlogrevision(ui, repo, file_, rev=None, cache=None, **opts):
500 def perfrevlogrevision(ui, repo, file_, rev=None, cache=None, **opts):
497 """Benchmark obtaining a revlog revision.
501 """Benchmark obtaining a revlog revision.
498
502
499 Obtaining a revlog revision consists of roughly the following steps:
503 Obtaining a revlog revision consists of roughly the following steps:
500
504
501 1. Compute the delta chain
505 1. Compute the delta chain
502 2. Obtain the raw chunks for that delta chain
506 2. Obtain the raw chunks for that delta chain
503 3. Decompress each raw chunk
507 3. Decompress each raw chunk
504 4. Apply binary patches to obtain fulltext
508 4. Apply binary patches to obtain fulltext
505 5. Verify hash of fulltext
509 5. Verify hash of fulltext
506
510
507 This command measures the time spent in each of these phases.
511 This command measures the time spent in each of these phases.
508 """
512 """
509 if opts.get('changelog') or opts.get('manifest'):
513 if opts.get('changelog') or opts.get('manifest'):
510 file_, rev = None, file_
514 file_, rev = None, file_
511 elif rev is None:
515 elif rev is None:
512 raise error.CommandError('perfrevlogrevision', 'invalid arguments')
516 raise error.CommandError('perfrevlogrevision', 'invalid arguments')
513
517
514 r = cmdutil.openrevlog(repo, 'perfrevlogrevision', file_, opts)
518 r = cmdutil.openrevlog(repo, 'perfrevlogrevision', file_, opts)
515 node = r.lookup(rev)
519 node = r.lookup(rev)
516 rev = r.rev(node)
520 rev = r.rev(node)
517
521
518 def dodeltachain(rev):
522 def dodeltachain(rev):
519 if not cache:
523 if not cache:
520 r.clearcaches()
524 r.clearcaches()
521 r._deltachain(rev)
525 r._deltachain(rev)
522
526
523 def doread(chain):
527 def doread(chain):
524 if not cache:
528 if not cache:
525 r.clearcaches()
529 r.clearcaches()
526 r._chunkraw(chain[0], chain[-1])
530 r._chunkraw(chain[0], chain[-1])
527
531
528 def dodecompress(data, chain):
532 def dodecompress(data, chain):
529 if not cache:
533 if not cache:
530 r.clearcaches()
534 r.clearcaches()
531
535
532 start = r.start
536 start = r.start
533 length = r.length
537 length = r.length
534 inline = r._inline
538 inline = r._inline
535 iosize = r._io.size
539 iosize = r._io.size
536 buffer = util.buffer
540 buffer = util.buffer
537 offset = start(chain[0])
541 offset = start(chain[0])
538
542
539 for rev in chain:
543 for rev in chain:
540 chunkstart = start(rev)
544 chunkstart = start(rev)
541 if inline:
545 if inline:
542 chunkstart += (rev + 1) * iosize
546 chunkstart += (rev + 1) * iosize
543 chunklength = length(rev)
547 chunklength = length(rev)
544 b = buffer(data, chunkstart - offset, chunklength)
548 b = buffer(data, chunkstart - offset, chunklength)
545 revlog.decompress(b)
549 revlog.decompress(b)
546
550
547 def dopatch(text, bins):
551 def dopatch(text, bins):
548 if not cache:
552 if not cache:
549 r.clearcaches()
553 r.clearcaches()
550 mdiff.patches(text, bins)
554 mdiff.patches(text, bins)
551
555
552 def dohash(text):
556 def dohash(text):
553 if not cache:
557 if not cache:
554 r.clearcaches()
558 r.clearcaches()
555 r._checkhash(text, node, rev)
559 r._checkhash(text, node, rev)
556
560
557 def dorevision():
561 def dorevision():
558 if not cache:
562 if not cache:
559 r.clearcaches()
563 r.clearcaches()
560 r.revision(node)
564 r.revision(node)
561
565
562 chain = r._deltachain(rev)[0]
566 chain = r._deltachain(rev)[0]
563 data = r._chunkraw(chain[0], chain[-1])
567 data = r._chunkraw(chain[0], chain[-1])
564 bins = r._chunks(chain)
568 bins = r._chunks(chain)
565 text = str(bins[0])
569 text = str(bins[0])
566 bins = bins[1:]
570 bins = bins[1:]
567 text = mdiff.patches(text, bins)
571 text = mdiff.patches(text, bins)
568
572
569 benches = [
573 benches = [
570 (lambda: dorevision(), 'full'),
574 (lambda: dorevision(), 'full'),
571 (lambda: dodeltachain(rev), 'deltachain'),
575 (lambda: dodeltachain(rev), 'deltachain'),
572 (lambda: doread(chain), 'read'),
576 (lambda: doread(chain), 'read'),
573 (lambda: dodecompress(data, chain), 'decompress'),
577 (lambda: dodecompress(data, chain), 'decompress'),
574 (lambda: dopatch(text, bins), 'patch'),
578 (lambda: dopatch(text, bins), 'patch'),
575 (lambda: dohash(text), 'hash'),
579 (lambda: dohash(text), 'hash'),
576 ]
580 ]
577
581
578 for fn, title in benches:
582 for fn, title in benches:
579 timer, fm = gettimer(ui, opts)
583 timer, fm = gettimer(ui, opts)
580 timer(fn, title=title)
584 timer(fn, title=title)
581 fm.end()
585 fm.end()
582
586
583 @command('perfrevset',
587 @command('perfrevset',
584 [('C', 'clear', False, 'clear volatile cache between each call.'),
588 [('C', 'clear', False, 'clear volatile cache between each call.'),
585 ('', 'contexts', False, 'obtain changectx for each revision')]
589 ('', 'contexts', False, 'obtain changectx for each revision')]
586 + formatteropts, "REVSET")
590 + formatteropts, "REVSET")
587 def perfrevset(ui, repo, expr, clear=False, contexts=False, **opts):
591 def perfrevset(ui, repo, expr, clear=False, contexts=False, **opts):
588 """benchmark the execution time of a revset
592 """benchmark the execution time of a revset
589
593
590 Use the --clean option if need to evaluate the impact of build volatile
594 Use the --clean option if need to evaluate the impact of build volatile
591 revisions set cache on the revset execution. Volatile cache hold filtered
595 revisions set cache on the revset execution. Volatile cache hold filtered
592 and obsolete related cache."""
596 and obsolete related cache."""
593 timer, fm = gettimer(ui, opts)
597 timer, fm = gettimer(ui, opts)
594 def d():
598 def d():
595 if clear:
599 if clear:
596 repo.invalidatevolatilesets()
600 repo.invalidatevolatilesets()
597 if contexts:
601 if contexts:
598 for ctx in repo.set(expr): pass
602 for ctx in repo.set(expr): pass
599 else:
603 else:
600 for r in repo.revs(expr): pass
604 for r in repo.revs(expr): pass
601 timer(d)
605 timer(d)
602 fm.end()
606 fm.end()
603
607
604 @command('perfvolatilesets', formatteropts)
608 @command('perfvolatilesets', formatteropts)
605 def perfvolatilesets(ui, repo, *names, **opts):
609 def perfvolatilesets(ui, repo, *names, **opts):
606 """benchmark the computation of various volatile set
610 """benchmark the computation of various volatile set
607
611
608 Volatile set computes element related to filtering and obsolescence."""
612 Volatile set computes element related to filtering and obsolescence."""
609 timer, fm = gettimer(ui, opts)
613 timer, fm = gettimer(ui, opts)
610 repo = repo.unfiltered()
614 repo = repo.unfiltered()
611
615
612 def getobs(name):
616 def getobs(name):
613 def d():
617 def d():
614 repo.invalidatevolatilesets()
618 repo.invalidatevolatilesets()
615 obsolete.getrevs(repo, name)
619 obsolete.getrevs(repo, name)
616 return d
620 return d
617
621
618 allobs = sorted(obsolete.cachefuncs)
622 allobs = sorted(obsolete.cachefuncs)
619 if names:
623 if names:
620 allobs = [n for n in allobs if n in names]
624 allobs = [n for n in allobs if n in names]
621
625
622 for name in allobs:
626 for name in allobs:
623 timer(getobs(name), title=name)
627 timer(getobs(name), title=name)
624
628
625 def getfiltered(name):
629 def getfiltered(name):
626 def d():
630 def d():
627 repo.invalidatevolatilesets()
631 repo.invalidatevolatilesets()
628 repoview.filterrevs(repo, name)
632 repoview.filterrevs(repo, name)
629 return d
633 return d
630
634
631 allfilter = sorted(repoview.filtertable)
635 allfilter = sorted(repoview.filtertable)
632 if names:
636 if names:
633 allfilter = [n for n in allfilter if n in names]
637 allfilter = [n for n in allfilter if n in names]
634
638
635 for name in allfilter:
639 for name in allfilter:
636 timer(getfiltered(name), title=name)
640 timer(getfiltered(name), title=name)
637 fm.end()
641 fm.end()
638
642
639 @command('perfbranchmap',
643 @command('perfbranchmap',
640 [('f', 'full', False,
644 [('f', 'full', False,
641 'Includes build time of subset'),
645 'Includes build time of subset'),
642 ] + formatteropts)
646 ] + formatteropts)
643 def perfbranchmap(ui, repo, full=False, **opts):
647 def perfbranchmap(ui, repo, full=False, **opts):
644 """benchmark the update of a branchmap
648 """benchmark the update of a branchmap
645
649
646 This benchmarks the full repo.branchmap() call with read and write disabled
650 This benchmarks the full repo.branchmap() call with read and write disabled
647 """
651 """
648 timer, fm = gettimer(ui, opts)
652 timer, fm = gettimer(ui, opts)
649 def getbranchmap(filtername):
653 def getbranchmap(filtername):
650 """generate a benchmark function for the filtername"""
654 """generate a benchmark function for the filtername"""
651 if filtername is None:
655 if filtername is None:
652 view = repo
656 view = repo
653 else:
657 else:
654 view = repo.filtered(filtername)
658 view = repo.filtered(filtername)
655 def d():
659 def d():
656 if full:
660 if full:
657 view._branchcaches.clear()
661 view._branchcaches.clear()
658 else:
662 else:
659 view._branchcaches.pop(filtername, None)
663 view._branchcaches.pop(filtername, None)
660 view.branchmap()
664 view.branchmap()
661 return d
665 return d
662 # add filter in smaller subset to bigger subset
666 # add filter in smaller subset to bigger subset
663 possiblefilters = set(repoview.filtertable)
667 possiblefilters = set(repoview.filtertable)
664 allfilters = []
668 allfilters = []
665 while possiblefilters:
669 while possiblefilters:
666 for name in possiblefilters:
670 for name in possiblefilters:
667 subset = branchmap.subsettable.get(name)
671 subset = branchmap.subsettable.get(name)
668 if subset not in possiblefilters:
672 if subset not in possiblefilters:
669 break
673 break
670 else:
674 else:
671 assert False, 'subset cycle %s!' % possiblefilters
675 assert False, 'subset cycle %s!' % possiblefilters
672 allfilters.append(name)
676 allfilters.append(name)
673 possiblefilters.remove(name)
677 possiblefilters.remove(name)
674
678
675 # warm the cache
679 # warm the cache
676 if not full:
680 if not full:
677 for name in allfilters:
681 for name in allfilters:
678 repo.filtered(name).branchmap()
682 repo.filtered(name).branchmap()
679 # add unfiltered
683 # add unfiltered
680 allfilters.append(None)
684 allfilters.append(None)
681 oldread = branchmap.read
685 oldread = branchmap.read
682 oldwrite = branchmap.branchcache.write
686 oldwrite = branchmap.branchcache.write
683 try:
687 try:
684 branchmap.read = lambda repo: None
688 branchmap.read = lambda repo: None
685 branchmap.write = lambda repo: None
689 branchmap.write = lambda repo: None
686 for name in allfilters:
690 for name in allfilters:
687 timer(getbranchmap(name), title=str(name))
691 timer(getbranchmap(name), title=str(name))
688 finally:
692 finally:
689 branchmap.read = oldread
693 branchmap.read = oldread
690 branchmap.branchcache.write = oldwrite
694 branchmap.branchcache.write = oldwrite
691 fm.end()
695 fm.end()
692
696
693 @command('perfloadmarkers')
697 @command('perfloadmarkers')
694 def perfloadmarkers(ui, repo):
698 def perfloadmarkers(ui, repo):
695 """benchmark the time to parse the on-disk markers for a repo
699 """benchmark the time to parse the on-disk markers for a repo
696
700
697 Result is the number of markers in the repo."""
701 Result is the number of markers in the repo."""
698 timer, fm = gettimer(ui)
702 timer, fm = gettimer(ui)
699 timer(lambda: len(obsolete.obsstore(repo.svfs)))
703 timer(lambda: len(obsolete.obsstore(repo.svfs)))
700 fm.end()
704 fm.end()
701
705
702 @command('perflrucachedict', formatteropts +
706 @command('perflrucachedict', formatteropts +
703 [('', 'size', 4, 'size of cache'),
707 [('', 'size', 4, 'size of cache'),
704 ('', 'gets', 10000, 'number of key lookups'),
708 ('', 'gets', 10000, 'number of key lookups'),
705 ('', 'sets', 10000, 'number of key sets'),
709 ('', 'sets', 10000, 'number of key sets'),
706 ('', 'mixed', 10000, 'number of mixed mode operations'),
710 ('', 'mixed', 10000, 'number of mixed mode operations'),
707 ('', 'mixedgetfreq', 50, 'frequency of get vs set ops in mixed mode')],
711 ('', 'mixedgetfreq', 50, 'frequency of get vs set ops in mixed mode')],
708 norepo=True)
712 norepo=True)
709 def perflrucache(ui, size=4, gets=10000, sets=10000, mixed=10000,
713 def perflrucache(ui, size=4, gets=10000, sets=10000, mixed=10000,
710 mixedgetfreq=50, **opts):
714 mixedgetfreq=50, **opts):
711 def doinit():
715 def doinit():
712 for i in xrange(10000):
716 for i in xrange(10000):
713 util.lrucachedict(size)
717 util.lrucachedict(size)
714
718
715 values = []
719 values = []
716 for i in xrange(size):
720 for i in xrange(size):
717 values.append(random.randint(0, sys.maxint))
721 values.append(random.randint(0, sys.maxint))
718
722
719 # Get mode fills the cache and tests raw lookup performance with no
723 # Get mode fills the cache and tests raw lookup performance with no
720 # eviction.
724 # eviction.
721 getseq = []
725 getseq = []
722 for i in xrange(gets):
726 for i in xrange(gets):
723 getseq.append(random.choice(values))
727 getseq.append(random.choice(values))
724
728
725 def dogets():
729 def dogets():
726 d = util.lrucachedict(size)
730 d = util.lrucachedict(size)
727 for v in values:
731 for v in values:
728 d[v] = v
732 d[v] = v
729 for key in getseq:
733 for key in getseq:
730 value = d[key]
734 value = d[key]
731 value # silence pyflakes warning
735 value # silence pyflakes warning
732
736
733 # Set mode tests insertion speed with cache eviction.
737 # Set mode tests insertion speed with cache eviction.
734 setseq = []
738 setseq = []
735 for i in xrange(sets):
739 for i in xrange(sets):
736 setseq.append(random.randint(0, sys.maxint))
740 setseq.append(random.randint(0, sys.maxint))
737
741
738 def dosets():
742 def dosets():
739 d = util.lrucachedict(size)
743 d = util.lrucachedict(size)
740 for v in setseq:
744 for v in setseq:
741 d[v] = v
745 d[v] = v
742
746
743 # Mixed mode randomly performs gets and sets with eviction.
747 # Mixed mode randomly performs gets and sets with eviction.
744 mixedops = []
748 mixedops = []
745 for i in xrange(mixed):
749 for i in xrange(mixed):
746 r = random.randint(0, 100)
750 r = random.randint(0, 100)
747 if r < mixedgetfreq:
751 if r < mixedgetfreq:
748 op = 0
752 op = 0
749 else:
753 else:
750 op = 1
754 op = 1
751
755
752 mixedops.append((op, random.randint(0, size * 2)))
756 mixedops.append((op, random.randint(0, size * 2)))
753
757
754 def domixed():
758 def domixed():
755 d = util.lrucachedict(size)
759 d = util.lrucachedict(size)
756
760
757 for op, v in mixedops:
761 for op, v in mixedops:
758 if op == 0:
762 if op == 0:
759 try:
763 try:
760 d[v]
764 d[v]
761 except KeyError:
765 except KeyError:
762 pass
766 pass
763 else:
767 else:
764 d[v] = v
768 d[v] = v
765
769
766 benches = [
770 benches = [
767 (doinit, 'init'),
771 (doinit, 'init'),
768 (dogets, 'gets'),
772 (dogets, 'gets'),
769 (dosets, 'sets'),
773 (dosets, 'sets'),
770 (domixed, 'mixed')
774 (domixed, 'mixed')
771 ]
775 ]
772
776
773 for fn, title in benches:
777 for fn, title in benches:
774 timer, fm = gettimer(ui, opts)
778 timer, fm = gettimer(ui, opts)
775 timer(fn, title=title)
779 timer(fn, title=title)
776 fm.end()
780 fm.end()
@@ -1,151 +1,151
1 #require test-repo
1 #require test-repo
2
2
3 Set vars:
3 Set vars:
4
4
5 $ CONTRIBDIR="$TESTDIR/../contrib"
5 $ CONTRIBDIR="$TESTDIR/../contrib"
6
6
7 Prepare repo:
7 Prepare repo:
8
8
9 $ hg init
9 $ hg init
10
10
11 $ echo this is file a > a
11 $ echo this is file a > a
12 $ hg add a
12 $ hg add a
13 $ hg commit -m first
13 $ hg commit -m first
14
14
15 $ echo adding to file a >> a
15 $ echo adding to file a >> a
16 $ hg commit -m second
16 $ hg commit -m second
17
17
18 $ echo adding more to file a >> a
18 $ echo adding more to file a >> a
19 $ hg commit -m third
19 $ hg commit -m third
20
20
21 $ hg up -r 0
21 $ hg up -r 0
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 $ echo merge-this >> a
23 $ echo merge-this >> a
24 $ hg commit -m merge-able
24 $ hg commit -m merge-able
25 created new head
25 created new head
26
26
27 $ hg up -r 2
27 $ hg up -r 2
28 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
29
29
30 perfstatus
30 perfstatus
31
31
32 $ cat >> $HGRCPATH << EOF
32 $ cat >> $HGRCPATH << EOF
33 > [extensions]
33 > [extensions]
34 > perfstatusext=$CONTRIBDIR/perf.py
34 > perfstatusext=$CONTRIBDIR/perf.py
35 > [perf]
35 > [perf]
36 > presleep=0
36 > presleep=0
37 > stub=on
37 > stub=on
38 > parentscount=1
38 > parentscount=1
39 > EOF
39 > EOF
40 $ hg help perfstatusext
40 $ hg help perfstatusext
41 perfstatusext extension - helper extension to measure performance
41 perfstatusext extension - helper extension to measure performance
42
42
43 list of commands:
43 list of commands:
44
44
45 perfaddremove
45 perfaddremove
46 (no help text available)
46 (no help text available)
47 perfancestors
47 perfancestors
48 (no help text available)
48 (no help text available)
49 perfancestorset
49 perfancestorset
50 (no help text available)
50 (no help text available)
51 perfannotate (no help text available)
51 perfannotate (no help text available)
52 perfbranchmap
52 perfbranchmap
53 benchmark the update of a branchmap
53 benchmark the update of a branchmap
54 perfcca (no help text available)
54 perfcca (no help text available)
55 perfchangeset
55 perfchangeset
56 (no help text available)
56 (no help text available)
57 perfctxfiles (no help text available)
57 perfctxfiles (no help text available)
58 perfdiffwd Profile diff of working directory changes
58 perfdiffwd Profile diff of working directory changes
59 perfdirfoldmap
59 perfdirfoldmap
60 (no help text available)
60 (no help text available)
61 perfdirs (no help text available)
61 perfdirs (no help text available)
62 perfdirstate (no help text available)
62 perfdirstate (no help text available)
63 perfdirstatedirs
63 perfdirstatedirs
64 (no help text available)
64 (no help text available)
65 perfdirstatefoldmap
65 perfdirstatefoldmap
66 (no help text available)
66 (no help text available)
67 perfdirstatewrite
67 perfdirstatewrite
68 (no help text available)
68 (no help text available)
69 perffncacheencode
69 perffncacheencode
70 (no help text available)
70 (no help text available)
71 perffncacheload
71 perffncacheload
72 (no help text available)
72 (no help text available)
73 perffncachewrite
73 perffncachewrite
74 (no help text available)
74 (no help text available)
75 perfheads (no help text available)
75 perfheads (no help text available)
76 perfindex (no help text available)
76 perfindex (no help text available)
77 perfloadmarkers
77 perfloadmarkers
78 benchmark the time to parse the on-disk markers for a repo
78 benchmark the time to parse the on-disk markers for a repo
79 perflog (no help text available)
79 perflog (no help text available)
80 perflookup (no help text available)
80 perflookup (no help text available)
81 perflrucachedict
81 perflrucachedict
82 (no help text available)
82 (no help text available)
83 perfmanifest (no help text available)
83 perfmanifest (no help text available)
84 perfmergecalculate
84 perfmergecalculate
85 (no help text available)
85 (no help text available)
86 perfmoonwalk benchmark walking the changelog backwards
86 perfmoonwalk benchmark walking the changelog backwards
87 perfnodelookup
87 perfnodelookup
88 (no help text available)
88 (no help text available)
89 perfparents (no help text available)
89 perfparents (no help text available)
90 perfpathcopies
90 perfpathcopies
91 (no help text available)
91 (no help text available)
92 perfrawfiles (no help text available)
92 perfrawfiles (no help text available)
93 perfrevlog (no help text available)
93 perfrevlog Benchmark reading a series of revisions from a revlog.
94 perfrevlogrevision
94 perfrevlogrevision
95 Benchmark obtaining a revlog revision.
95 Benchmark obtaining a revlog revision.
96 perfrevrange (no help text available)
96 perfrevrange (no help text available)
97 perfrevset benchmark the execution time of a revset
97 perfrevset benchmark the execution time of a revset
98 perfstartup (no help text available)
98 perfstartup (no help text available)
99 perfstatus (no help text available)
99 perfstatus (no help text available)
100 perftags (no help text available)
100 perftags (no help text available)
101 perftemplating
101 perftemplating
102 (no help text available)
102 (no help text available)
103 perfvolatilesets
103 perfvolatilesets
104 benchmark the computation of various volatile set
104 benchmark the computation of various volatile set
105 perfwalk (no help text available)
105 perfwalk (no help text available)
106
106
107 (use "hg help -v perfstatusext" to show built-in aliases and global options)
107 (use "hg help -v perfstatusext" to show built-in aliases and global options)
108 $ hg perfaddremove
108 $ hg perfaddremove
109 $ hg perfancestors
109 $ hg perfancestors
110 $ hg perfancestorset 2
110 $ hg perfancestorset 2
111 $ hg perfannotate a
111 $ hg perfannotate a
112 $ hg perfbranchmap
112 $ hg perfbranchmap
113 $ hg perfcca
113 $ hg perfcca
114 $ hg perfchangeset 2
114 $ hg perfchangeset 2
115 $ hg perfctxfiles 2
115 $ hg perfctxfiles 2
116 $ hg perfdiffwd
116 $ hg perfdiffwd
117 $ hg perfdirfoldmap
117 $ hg perfdirfoldmap
118 $ hg perfdirs
118 $ hg perfdirs
119 $ hg perfdirstate
119 $ hg perfdirstate
120 $ hg perfdirstatedirs
120 $ hg perfdirstatedirs
121 $ hg perfdirstatefoldmap
121 $ hg perfdirstatefoldmap
122 $ hg perfdirstatewrite
122 $ hg perfdirstatewrite
123 $ hg perffncacheencode
123 $ hg perffncacheencode
124 $ hg perffncacheload
124 $ hg perffncacheload
125 $ hg perffncachewrite
125 $ hg perffncachewrite
126 transaction abort!
126 transaction abort!
127 rollback completed
127 rollback completed
128 $ hg perfheads
128 $ hg perfheads
129 $ hg perfindex
129 $ hg perfindex
130 $ hg perfloadmarkers
130 $ hg perfloadmarkers
131 $ hg perflog
131 $ hg perflog
132 $ hg perflookup 2
132 $ hg perflookup 2
133 $ hg perflrucache
133 $ hg perflrucache
134 $ hg perfmanifest 2
134 $ hg perfmanifest 2
135 $ hg perfmergecalculate -r 3
135 $ hg perfmergecalculate -r 3
136 $ hg perfmoonwalk
136 $ hg perfmoonwalk
137 $ hg perfnodelookup 2
137 $ hg perfnodelookup 2
138 $ hg perfpathcopies 1 2
138 $ hg perfpathcopies 1 2
139 $ hg perfrawfiles 2
139 $ hg perfrawfiles 2
140 $ hg perfrevlog .hg/store/data/a.i
140 $ hg perfrevlog .hg/store/data/a.i
141 $ hg perfrevlogrevision -m 0
141 $ hg perfrevlogrevision -m 0
142 $ hg perfrevrange
142 $ hg perfrevrange
143 $ hg perfrevset 'all()'
143 $ hg perfrevset 'all()'
144 $ hg perfstartup
144 $ hg perfstartup
145 $ hg perfstatus
145 $ hg perfstatus
146 $ hg perftags
146 $ hg perftags
147 $ hg perftemplating
147 $ hg perftemplating
148 $ hg perfvolatilesets
148 $ hg perfvolatilesets
149 $ hg perfwalk
149 $ hg perfwalk
150 $ hg perfparents
150 $ hg perfparents
151
151
General Comments 0
You need to be logged in to leave comments. Login now