180 fm.write('user', ' user %f', m[1]) |
180 fm.write('user', ' user %f', m[1]) |
181 fm.write('sys', ' sys %f', m[2]) |
181 fm.write('sys', ' sys %f', m[2]) |
182 fm.write('count', ' (best of %d)', count) |
182 fm.write('count', ' (best of %d)', count) |
183 fm.plain('\n') |
183 fm.plain('\n') |
184 |
184 |
|
185 # utilities for historical portability |
|
186 |
|
187 def safeattrsetter(obj, name, ignoremissing=False): |
|
188 """Ensure that 'obj' has 'name' attribute before subsequent setattr |
|
189 |
|
190 This function is aborted, if 'obj' doesn't have 'name' attribute |
|
191 at runtime. This avoids overlooking removal of an attribute, which |
|
192 breaks assumption of performance measurement, in the future. |
|
193 |
|
194 This function returns the object to (1) assign a new value, and |
|
195 (2) restore an original value to the attribute. |
|
196 |
|
197 If 'ignoremissing' is true, missing 'name' attribute doesn't cause |
|
198 abortion, and this function returns None. This is useful to |
|
199 examine an attribute, which isn't ensured in all Mercurial |
|
200 versions. |
|
201 """ |
|
202 if not util.safehasattr(obj, name): |
|
203 if ignoremissing: |
|
204 return None |
|
205 raise error.Abort(("missing attribute %s of %s might break assumption" |
|
206 " of performance measurement") % (name, obj)) |
|
207 |
|
208 origvalue = getattr(obj, name) |
|
209 class attrutil(object): |
|
210 def set(self, newvalue): |
|
211 setattr(obj, name, newvalue) |
|
212 def restore(self): |
|
213 setattr(obj, name, origvalue) |
|
214 |
|
215 return attrutil() |
|
216 |
|
217 # perf commands |
|
218 |
185 @command('perfwalk', formatteropts) |
219 @command('perfwalk', formatteropts) |
186 def perfwalk(ui, repo, *pats, **opts): |
220 def perfwalk(ui, repo, *pats, **opts): |
187 timer, fm = gettimer(ui, opts) |
221 timer, fm = gettimer(ui, opts) |
188 try: |
222 try: |
189 m = scmutil.match(repo[None], pats, {}) |
223 m = scmutil.match(repo[None], pats, {}) |