##// END OF EJS Templates
perftest: allow selection of volatile set to benchmark...
Pierre-Yves David -
r18241:f5ed27c5 default
parent child Browse files
Show More
@@ -1,303 +1,311
1 1 # perf.py - performance test routines
2 2 '''helper extension to measure performance'''
3 3
4 4 from mercurial import cmdutil, scmutil, util, match, commands, obsolete
5 5 from mercurial import repoview
6 6 import time, os, sys
7 7
8 8 cmdtable = {}
9 9 command = cmdutil.command(cmdtable)
10 10
11 11 def timer(func, title=None):
12 12 results = []
13 13 begin = time.time()
14 14 count = 0
15 15 while True:
16 16 ostart = os.times()
17 17 cstart = time.time()
18 18 r = func()
19 19 cstop = time.time()
20 20 ostop = os.times()
21 21 count += 1
22 22 a, b = ostart, ostop
23 23 results.append((cstop - cstart, b[0] - a[0], b[1]-a[1]))
24 24 if cstop - begin > 3 and count >= 100:
25 25 break
26 26 if cstop - begin > 10 and count >= 3:
27 27 break
28 28 if title:
29 29 sys.stderr.write("! %s\n" % title)
30 30 if r:
31 31 sys.stderr.write("! result: %s\n" % r)
32 32 m = min(results)
33 33 sys.stderr.write("! wall %f comb %f user %f sys %f (best of %d)\n"
34 34 % (m[0], m[1] + m[2], m[1], m[2], count))
35 35
36 36 @command('perfwalk')
37 37 def perfwalk(ui, repo, *pats):
38 38 try:
39 39 m = scmutil.match(repo[None], pats, {})
40 40 timer(lambda: len(list(repo.dirstate.walk(m, [], True, False))))
41 41 except Exception:
42 42 try:
43 43 m = scmutil.match(repo[None], pats, {})
44 44 timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)]))
45 45 except Exception:
46 46 timer(lambda: len(list(cmdutil.walk(repo, pats, {}))))
47 47
48 48 @command('perfstatus',
49 49 [('u', 'unknown', False,
50 50 'ask status to look for unknown files')])
51 51 def perfstatus(ui, repo, **opts):
52 52 #m = match.always(repo.root, repo.getcwd())
53 53 #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False,
54 54 # False))))
55 55 timer(lambda: sum(map(len, repo.status(**opts))))
56 56
57 57 def clearcaches(cl):
58 58 # behave somewhat consistently across internal API changes
59 59 if util.safehasattr(cl, 'clearcaches'):
60 60 cl.clearcaches()
61 61 elif util.safehasattr(cl, '_nodecache'):
62 62 from mercurial.node import nullid, nullrev
63 63 cl._nodecache = {nullid: nullrev}
64 64 cl._nodepos = None
65 65
66 66 @command('perfheads')
67 67 def perfheads(ui, repo):
68 68 cl = repo.changelog
69 69 def d():
70 70 len(cl.headrevs())
71 71 clearcaches(cl)
72 72 timer(d)
73 73
74 74 @command('perftags')
75 75 def perftags(ui, repo):
76 76 import mercurial.changelog, mercurial.manifest
77 77 def t():
78 78 repo.changelog = mercurial.changelog.changelog(repo.sopener)
79 79 repo.manifest = mercurial.manifest.manifest(repo.sopener)
80 80 repo._tags = None
81 81 return len(repo.tags())
82 82 timer(t)
83 83
84 84 @command('perfancestors')
85 85 def perfancestors(ui, repo):
86 86 heads = repo.changelog.headrevs()
87 87 def d():
88 88 for a in repo.changelog.ancestors(heads):
89 89 pass
90 90 timer(d)
91 91
92 92 @command('perfancestorset')
93 93 def perfancestorset(ui, repo, revset):
94 94 revs = repo.revs(revset)
95 95 heads = repo.changelog.headrevs()
96 96 def d():
97 97 s = repo.changelog.ancestors(heads)
98 98 for rev in revs:
99 99 rev in s
100 100 timer(d)
101 101
102 102 @command('perfdirstate')
103 103 def perfdirstate(ui, repo):
104 104 "a" in repo.dirstate
105 105 def d():
106 106 repo.dirstate.invalidate()
107 107 "a" in repo.dirstate
108 108 timer(d)
109 109
110 110 @command('perfdirstatedirs')
111 111 def perfdirstatedirs(ui, repo):
112 112 "a" in repo.dirstate
113 113 def d():
114 114 "a" in repo.dirstate._dirs
115 115 del repo.dirstate._dirs
116 116 timer(d)
117 117
118 118 @command('perfdirstatewrite')
119 119 def perfdirstatewrite(ui, repo):
120 120 ds = repo.dirstate
121 121 "a" in ds
122 122 def d():
123 123 ds._dirty = True
124 124 ds.write()
125 125 timer(d)
126 126
127 127 @command('perfmanifest')
128 128 def perfmanifest(ui, repo):
129 129 def d():
130 130 t = repo.manifest.tip()
131 131 m = repo.manifest.read(t)
132 132 repo.manifest.mapcache = None
133 133 repo.manifest._cache = None
134 134 timer(d)
135 135
136 136 @command('perfchangeset')
137 137 def perfchangeset(ui, repo, rev):
138 138 n = repo[rev].node()
139 139 def d():
140 140 c = repo.changelog.read(n)
141 141 #repo.changelog._cache = None
142 142 timer(d)
143 143
144 144 @command('perfindex')
145 145 def perfindex(ui, repo):
146 146 import mercurial.revlog
147 147 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
148 148 n = repo["tip"].node()
149 149 def d():
150 150 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i")
151 151 cl.rev(n)
152 152 timer(d)
153 153
154 154 @command('perfstartup')
155 155 def perfstartup(ui, repo):
156 156 cmd = sys.argv[0]
157 157 def d():
158 158 os.system("HGRCPATH= %s version -q > /dev/null" % cmd)
159 159 timer(d)
160 160
161 161 @command('perfparents')
162 162 def perfparents(ui, repo):
163 163 nl = [repo.changelog.node(i) for i in xrange(1000)]
164 164 def d():
165 165 for n in nl:
166 166 repo.changelog.parents(n)
167 167 timer(d)
168 168
169 169 @command('perflookup')
170 170 def perflookup(ui, repo, rev):
171 171 timer(lambda: len(repo.lookup(rev)))
172 172
173 173 @command('perfrevrange')
174 174 def perfrevrange(ui, repo, *specs):
175 175 revrange = scmutil.revrange
176 176 timer(lambda: len(revrange(repo, specs)))
177 177
178 178 @command('perfnodelookup')
179 179 def perfnodelookup(ui, repo, rev):
180 180 import mercurial.revlog
181 181 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
182 182 n = repo[rev].node()
183 183 cl = mercurial.revlog.revlog(repo.sopener, "00changelog.i")
184 184 def d():
185 185 cl.rev(n)
186 186 clearcaches(cl)
187 187 timer(d)
188 188
189 189 @command('perflog',
190 190 [('', 'rename', False, 'ask log to follow renames')])
191 191 def perflog(ui, repo, **opts):
192 192 ui.pushbuffer()
193 193 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
194 194 copies=opts.get('rename')))
195 195 ui.popbuffer()
196 196
197 197 @command('perftemplating')
198 198 def perftemplating(ui, repo):
199 199 ui.pushbuffer()
200 200 timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
201 201 template='{date|shortdate} [{rev}:{node|short}]'
202 202 ' {author|person}: {desc|firstline}\n'))
203 203 ui.popbuffer()
204 204
205 205 @command('perfcca')
206 206 def perfcca(ui, repo):
207 207 timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
208 208
209 209 @command('perffncacheload')
210 210 def perffncacheload(ui, repo):
211 211 s = repo.store
212 212 def d():
213 213 s.fncache._load()
214 214 timer(d)
215 215
216 216 @command('perffncachewrite')
217 217 def perffncachewrite(ui, repo):
218 218 s = repo.store
219 219 s.fncache._load()
220 220 def d():
221 221 s.fncache._dirty = True
222 222 s.fncache.write()
223 223 timer(d)
224 224
225 225 @command('perffncacheencode')
226 226 def perffncacheencode(ui, repo):
227 227 s = repo.store
228 228 s.fncache._load()
229 229 def d():
230 230 for p in s.fncache.entries:
231 231 s.encode(p)
232 232 timer(d)
233 233
234 234 @command('perfdiffwd')
235 235 def perfdiffwd(ui, repo):
236 236 """Profile diff of working directory changes"""
237 237 options = {
238 238 'w': 'ignore_all_space',
239 239 'b': 'ignore_space_change',
240 240 'B': 'ignore_blank_lines',
241 241 }
242 242
243 243 for diffopt in ('', 'w', 'b', 'B', 'wB'):
244 244 opts = dict((options[c], '1') for c in diffopt)
245 245 def d():
246 246 ui.pushbuffer()
247 247 commands.diff(ui, repo, **opts)
248 248 ui.popbuffer()
249 249 title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none')
250 250 timer(d, title)
251 251
252 252 @command('perfrevlog',
253 253 [('d', 'dist', 100, 'distance between the revisions')],
254 254 "[INDEXFILE]")
255 255 def perfrevlog(ui, repo, file_, **opts):
256 256 from mercurial import revlog
257 257 dist = opts['dist']
258 258 def d():
259 259 r = revlog.revlog(lambda fn: open(fn, 'rb'), file_)
260 260 for x in xrange(0, len(r), dist):
261 261 r.revision(r.node(x))
262 262
263 263 timer(d)
264 264
265 265 @command('perfrevset',
266 266 [('C', 'clear', False, 'clear volatile cache between each call.')],
267 267 "REVSET")
268 268 def perfrevset(ui, repo, expr, clear=False):
269 269 """benchmark the execution time of a revset
270 270
271 271 Use the --clean option if need to evaluate the impact of build volative
272 272 revisions set cache on the revset execution. Volatile cache hold filtered
273 273 and obsolete related cache."""
274 274 def d():
275 275 if clear:
276 276 repo.invalidatevolatilesets()
277 277 repo.revs(expr)
278 278 timer(d)
279 279
280 280 @command('perfvolatilesets')
281 def perfvolatilesets(ui, repo):
281 def perfvolatilesets(ui, repo, *names):
282 282 """benchmark the computation of various volatile set
283 283
284 284 Volatile set computes element related to filtering and obsolescence."""
285 285 repo = repo.unfiltered()
286 286
287 287 def getobs(name):
288 288 def d():
289 289 repo.invalidatevolatilesets()
290 290 obsolete.getrevs(repo, name)
291 291 return d
292 292
293 for name in sorted(obsolete.cachefuncs):
293 allobs = sorted(obsolete.cachefuncs)
294 if names:
295 allobs = [n for n in allobs if n in names]
296
297 for name in allobs:
294 298 timer(getobs(name), title=name)
295 299
296 300 def getfiltered(name):
297 301 def d():
298 302 repo.invalidatevolatilesets()
299 303 repoview.filteredrevs(repo, name)
300 304 return d
301 305
302 for name in sorted(repoview.filtertable):
306 allfilter = sorted(repoview.filtertable)
307 if names:
308 allfilter = [n for n in allfilter if n in names]
309
310 for name in allfilter:
303 311 timer(getfiltered(name), title=name)
General Comments 0
You need to be logged in to leave comments. Login now