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