242 self._ui.write(deftext % fielddata, **opts) |
260 self._ui.write(deftext % fielddata, **opts) |
243 def plain(self, text, **opts): |
261 def plain(self, text, **opts): |
244 self._ui.write(text, **opts) |
262 self._ui.write(text, **opts) |
245 def end(self): |
263 def end(self): |
246 pass |
264 pass |
247 fm = defaultformatter(ui, 'perf', opts) |
265 fm = defaultformatter(ui, b'perf', opts) |
248 |
266 |
249 # stub function, runs code only once instead of in a loop |
267 # stub function, runs code only once instead of in a loop |
250 # experimental config: perf.stub |
268 # experimental config: perf.stub |
251 if ui.configbool("perf", "stub", False): |
269 if ui.configbool(b"perf", b"stub", False): |
252 return functools.partial(stub_timer, fm), fm |
270 return functools.partial(stub_timer, fm), fm |
253 |
271 |
254 # experimental config: perf.all-timing |
272 # experimental config: perf.all-timing |
255 displayall = ui.configbool("perf", "all-timing", False) |
273 displayall = ui.configbool(b"perf", b"all-timing", False) |
256 return functools.partial(_timer, fm, displayall=displayall), fm |
274 return functools.partial(_timer, fm, displayall=displayall), fm |
257 |
275 |
258 def stub_timer(fm, func, title=None): |
276 def stub_timer(fm, func, title=None): |
259 func() |
277 func() |
|
278 |
|
279 @contextlib.contextmanager |
|
280 def timeone(): |
|
281 r = [] |
|
282 ostart = os.times() |
|
283 cstart = util.timer() |
|
284 yield r |
|
285 cstop = util.timer() |
|
286 ostop = os.times() |
|
287 a, b = ostart, ostop |
|
288 r.append((cstop - cstart, b[0] - a[0], b[1]-a[1])) |
260 |
289 |
261 def _timer(fm, func, title=None, displayall=False): |
290 def _timer(fm, func, title=None, displayall=False): |
262 gc.collect() |
291 gc.collect() |
263 results = [] |
292 results = [] |
264 begin = util.timer() |
293 begin = util.timer() |
265 count = 0 |
294 count = 0 |
266 while True: |
295 while True: |
267 ostart = os.times() |
296 with timeone() as item: |
268 cstart = util.timer() |
297 r = func() |
269 r = func() |
298 count += 1 |
|
299 results.append(item[0]) |
270 cstop = util.timer() |
300 cstop = util.timer() |
271 ostop = os.times() |
|
272 count += 1 |
|
273 a, b = ostart, ostop |
|
274 results.append((cstop - cstart, b[0] - a[0], b[1]-a[1])) |
|
275 if cstop - begin > 3 and count >= 100: |
301 if cstop - begin > 3 and count >= 100: |
276 break |
302 break |
277 if cstop - begin > 10 and count >= 3: |
303 if cstop - begin > 10 and count >= 3: |
278 break |
304 break |
279 |
305 |
|
306 formatone(fm, results, title=title, result=r, |
|
307 displayall=displayall) |
|
308 |
|
309 def formatone(fm, timings, title=None, result=None, displayall=False): |
|
310 |
|
311 count = len(timings) |
|
312 |
280 fm.startitem() |
313 fm.startitem() |
281 |
314 |
282 if title: |
315 if title: |
283 fm.write('title', '! %s\n', title) |
316 fm.write(b'title', b'! %s\n', title) |
284 if r: |
317 if result: |
285 fm.write('result', '! result: %s\n', r) |
318 fm.write(b'result', b'! result: %s\n', result) |
286 def display(role, entry): |
319 def display(role, entry): |
287 prefix = '' |
320 prefix = b'' |
288 if role != 'best': |
321 if role != b'best': |
289 prefix = '%s.' % role |
322 prefix = b'%s.' % role |
290 fm.plain('!') |
323 fm.plain(b'!') |
291 fm.write(prefix + 'wall', ' wall %f', entry[0]) |
324 fm.write(prefix + b'wall', b' wall %f', entry[0]) |
292 fm.write(prefix + 'comb', ' comb %f', entry[1] + entry[2]) |
325 fm.write(prefix + b'comb', b' comb %f', entry[1] + entry[2]) |
293 fm.write(prefix + 'user', ' user %f', entry[1]) |
326 fm.write(prefix + b'user', b' user %f', entry[1]) |
294 fm.write(prefix + 'sys', ' sys %f', entry[2]) |
327 fm.write(prefix + b'sys', b' sys %f', entry[2]) |
295 fm.write(prefix + 'count', ' (%s of %d)', role, count) |
328 fm.write(prefix + b'count', b' (%s of %%d)' % role, count) |
296 fm.plain('\n') |
329 fm.plain(b'\n') |
297 results.sort() |
330 timings.sort() |
298 min_val = results[0] |
331 min_val = timings[0] |
299 display('best', min_val) |
332 display(b'best', min_val) |
300 if displayall: |
333 if displayall: |
301 max_val = results[-1] |
334 max_val = timings[-1] |
302 display('max', max_val) |
335 display(b'max', max_val) |
303 avg = tuple([sum(x) / count for x in zip(*results)]) |
336 avg = tuple([sum(x) / count for x in zip(*timings)]) |
304 display('avg', avg) |
337 display(b'avg', avg) |
305 median = results[len(results) // 2] |
338 median = timings[len(timings) // 2] |
306 display('median', median) |
339 display(b'median', median) |
307 |
340 |
308 # utilities for historical portability |
341 # utilities for historical portability |
309 |
342 |
310 def getint(ui, section, name, default): |
343 def getint(ui, section, name, default): |
311 # for "historical portability": |
344 # for "historical portability": |
426 delattr(unfi, attrname) |
459 delattr(unfi, attrname) |
427 unfi._filecache.pop(attrname, None) |
460 unfi._filecache.pop(attrname, None) |
428 |
461 |
429 # perf commands |
462 # perf commands |
430 |
463 |
431 @command('perfwalk', formatteropts) |
464 @command(b'perfwalk', formatteropts) |
432 def perfwalk(ui, repo, *pats, **opts): |
465 def perfwalk(ui, repo, *pats, **opts): |
|
466 opts = _byteskwargs(opts) |
433 timer, fm = gettimer(ui, opts) |
467 timer, fm = gettimer(ui, opts) |
434 m = scmutil.match(repo[None], pats, {}) |
468 m = scmutil.match(repo[None], pats, {}) |
435 timer(lambda: len(list(repo.dirstate.walk(m, subrepos=[], unknown=True, |
469 timer(lambda: len(list(repo.dirstate.walk(m, subrepos=[], unknown=True, |
436 ignored=False)))) |
470 ignored=False)))) |
437 fm.end() |
471 fm.end() |
438 |
472 |
439 @command('perfannotate', formatteropts) |
473 @command(b'perfannotate', formatteropts) |
440 def perfannotate(ui, repo, f, **opts): |
474 def perfannotate(ui, repo, f, **opts): |
441 timer, fm = gettimer(ui, opts) |
475 opts = _byteskwargs(opts) |
442 fc = repo['.'][f] |
476 timer, fm = gettimer(ui, opts) |
|
477 fc = repo[b'.'][f] |
443 timer(lambda: len(fc.annotate(True))) |
478 timer(lambda: len(fc.annotate(True))) |
444 fm.end() |
479 fm.end() |
445 |
480 |
446 @command('perfstatus', |
481 @command(b'perfstatus', |
447 [('u', 'unknown', False, |
482 [(b'u', b'unknown', False, |
448 'ask status to look for unknown files')] + formatteropts) |
483 b'ask status to look for unknown files')] + formatteropts) |
449 def perfstatus(ui, repo, **opts): |
484 def perfstatus(ui, repo, **opts): |
|
485 opts = _byteskwargs(opts) |
450 #m = match.always(repo.root, repo.getcwd()) |
486 #m = match.always(repo.root, repo.getcwd()) |
451 #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False, |
487 #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False, |
452 # False)))) |
488 # False)))) |
453 timer, fm = gettimer(ui, opts) |
489 timer, fm = gettimer(ui, opts) |
454 timer(lambda: sum(map(len, repo.status(unknown=opts['unknown'])))) |
490 timer(lambda: sum(map(len, repo.status(unknown=opts[b'unknown'])))) |
455 fm.end() |
491 fm.end() |
456 |
492 |
457 @command('perfaddremove', formatteropts) |
493 @command(b'perfaddremove', formatteropts) |
458 def perfaddremove(ui, repo, **opts): |
494 def perfaddremove(ui, repo, **opts): |
|
495 opts = _byteskwargs(opts) |
459 timer, fm = gettimer(ui, opts) |
496 timer, fm = gettimer(ui, opts) |
460 try: |
497 try: |
461 oldquiet = repo.ui.quiet |
498 oldquiet = repo.ui.quiet |
462 repo.ui.quiet = True |
499 repo.ui.quiet = True |
463 matcher = scmutil.match(repo[None]) |
500 matcher = scmutil.match(repo[None]) |
464 opts['dry_run'] = True |
501 opts[b'dry_run'] = True |
465 timer(lambda: scmutil.addremove(repo, matcher, "", opts)) |
502 timer(lambda: scmutil.addremove(repo, matcher, b"", opts)) |
466 finally: |
503 finally: |
467 repo.ui.quiet = oldquiet |
504 repo.ui.quiet = oldquiet |
468 fm.end() |
505 fm.end() |
469 |
506 |
470 def clearcaches(cl): |
507 def clearcaches(cl): |
471 # behave somewhat consistently across internal API changes |
508 # behave somewhat consistently across internal API changes |
472 if util.safehasattr(cl, 'clearcaches'): |
509 if util.safehasattr(cl, b'clearcaches'): |
473 cl.clearcaches() |
510 cl.clearcaches() |
474 elif util.safehasattr(cl, '_nodecache'): |
511 elif util.safehasattr(cl, b'_nodecache'): |
475 from mercurial.node import nullid, nullrev |
512 from mercurial.node import nullid, nullrev |
476 cl._nodecache = {nullid: nullrev} |
513 cl._nodecache = {nullid: nullrev} |
477 cl._nodepos = None |
514 cl._nodepos = None |
478 |
515 |
479 @command('perfheads', formatteropts) |
516 @command(b'perfheads', formatteropts) |
480 def perfheads(ui, repo, **opts): |
517 def perfheads(ui, repo, **opts): |
|
518 opts = _byteskwargs(opts) |
481 timer, fm = gettimer(ui, opts) |
519 timer, fm = gettimer(ui, opts) |
482 cl = repo.changelog |
520 cl = repo.changelog |
483 def d(): |
521 def d(): |
484 len(cl.headrevs()) |
522 len(cl.headrevs()) |
485 clearcaches(cl) |
523 clearcaches(cl) |
486 timer(d) |
524 timer(d) |
487 fm.end() |
525 fm.end() |
488 |
526 |
489 @command('perftags', formatteropts) |
527 @command(b'perftags', formatteropts) |
490 def perftags(ui, repo, **opts): |
528 def perftags(ui, repo, **opts): |
491 import mercurial.changelog |
529 import mercurial.changelog |
492 import mercurial.manifest |
530 import mercurial.manifest |
|
531 |
|
532 opts = _byteskwargs(opts) |
493 timer, fm = gettimer(ui, opts) |
533 timer, fm = gettimer(ui, opts) |
494 svfs = getsvfs(repo) |
534 svfs = getsvfs(repo) |
495 repocleartagscache = repocleartagscachefunc(repo) |
535 repocleartagscache = repocleartagscachefunc(repo) |
496 def t(): |
536 def t(): |
497 repo.changelog = mercurial.changelog.changelog(svfs) |
537 repo.changelog = mercurial.changelog.changelog(svfs) |
498 repo.manifestlog = mercurial.manifest.manifestlog(svfs, repo) |
538 rootmanifest = mercurial.manifest.manifestrevlog(svfs) |
|
539 repo.manifestlog = mercurial.manifest.manifestlog(svfs, repo, |
|
540 rootmanifest) |
499 repocleartagscache() |
541 repocleartagscache() |
500 return len(repo.tags()) |
542 return len(repo.tags()) |
501 timer(t) |
543 timer(t) |
502 fm.end() |
544 fm.end() |
503 |
545 |
504 @command('perfancestors', formatteropts) |
546 @command(b'perfancestors', formatteropts) |
505 def perfancestors(ui, repo, **opts): |
547 def perfancestors(ui, repo, **opts): |
|
548 opts = _byteskwargs(opts) |
506 timer, fm = gettimer(ui, opts) |
549 timer, fm = gettimer(ui, opts) |
507 heads = repo.changelog.headrevs() |
550 heads = repo.changelog.headrevs() |
508 def d(): |
551 def d(): |
509 for a in repo.changelog.ancestors(heads): |
552 for a in repo.changelog.ancestors(heads): |
510 pass |
553 pass |
511 timer(d) |
554 timer(d) |
512 fm.end() |
555 fm.end() |
513 |
556 |
514 @command('perfancestorset', formatteropts) |
557 @command(b'perfancestorset', formatteropts) |
515 def perfancestorset(ui, repo, revset, **opts): |
558 def perfancestorset(ui, repo, revset, **opts): |
|
559 opts = _byteskwargs(opts) |
516 timer, fm = gettimer(ui, opts) |
560 timer, fm = gettimer(ui, opts) |
517 revs = repo.revs(revset) |
561 revs = repo.revs(revset) |
518 heads = repo.changelog.headrevs() |
562 heads = repo.changelog.headrevs() |
519 def d(): |
563 def d(): |
520 s = repo.changelog.ancestors(heads) |
564 s = repo.changelog.ancestors(heads) |
521 for rev in revs: |
565 for rev in revs: |
522 rev in s |
566 rev in s |
523 timer(d) |
567 timer(d) |
524 fm.end() |
568 fm.end() |
525 |
569 |
526 @command('perfbookmarks', formatteropts) |
570 @command(b'perfbookmarks', formatteropts) |
527 def perfbookmarks(ui, repo, **opts): |
571 def perfbookmarks(ui, repo, **opts): |
528 """benchmark parsing bookmarks from disk to memory""" |
572 """benchmark parsing bookmarks from disk to memory""" |
529 timer, fm = gettimer(ui, opts) |
573 opts = _byteskwargs(opts) |
530 def d(): |
574 timer, fm = gettimer(ui, opts) |
531 clearfilecache(repo, '_bookmarks') |
575 def d(): |
|
576 clearfilecache(repo, b'_bookmarks') |
532 repo._bookmarks |
577 repo._bookmarks |
533 timer(d) |
578 timer(d) |
534 fm.end() |
579 fm.end() |
535 |
580 |
536 @command('perfbundleread', formatteropts, 'BUNDLE') |
581 @command(b'perfbundleread', formatteropts, b'BUNDLE') |
537 def perfbundleread(ui, repo, bundlepath, **opts): |
582 def perfbundleread(ui, repo, bundlepath, **opts): |
538 """Benchmark reading of bundle files. |
583 """Benchmark reading of bundle files. |
539 |
584 |
540 This command is meant to isolate the I/O part of bundle reading as |
585 This command is meant to isolate the I/O part of bundle reading as |
541 much as possible. |
586 much as possible. |
599 for part in bundle.iterparts(seekable=True): |
646 for part in bundle.iterparts(seekable=True): |
600 part.seek(0, os.SEEK_END) |
647 part.seek(0, os.SEEK_END) |
601 |
648 |
602 def makepartreadnbytes(size): |
649 def makepartreadnbytes(size): |
603 def run(): |
650 def run(): |
604 with open(bundlepath, 'rb') as fh: |
651 with open(bundlepath, b'rb') as fh: |
605 bundle = exchange.readbundle(ui, fh, bundlepath) |
652 bundle = exchange.readbundle(ui, fh, bundlepath) |
606 for part in bundle.iterparts(): |
653 for part in bundle.iterparts(): |
607 while part.read(size): |
654 while part.read(size): |
608 pass |
655 pass |
609 |
656 |
610 return run |
657 return run |
611 |
658 |
612 benches = [ |
659 benches = [ |
613 (makestdioread(8192), 'read(8k)'), |
660 (makestdioread(8192), b'read(8k)'), |
614 (makestdioread(16384), 'read(16k)'), |
661 (makestdioread(16384), b'read(16k)'), |
615 (makestdioread(32768), 'read(32k)'), |
662 (makestdioread(32768), b'read(32k)'), |
616 (makestdioread(131072), 'read(128k)'), |
663 (makestdioread(131072), b'read(128k)'), |
617 ] |
664 ] |
618 |
665 |
619 with open(bundlepath, 'rb') as fh: |
666 with open(bundlepath, b'rb') as fh: |
620 bundle = exchange.readbundle(ui, fh, bundlepath) |
667 bundle = exchange.readbundle(ui, fh, bundlepath) |
621 |
668 |
622 if isinstance(bundle, changegroup.cg1unpacker): |
669 if isinstance(bundle, changegroup.cg1unpacker): |
623 benches.extend([ |
670 benches.extend([ |
624 (makebench(deltaiter), 'cg1 deltaiter()'), |
671 (makebench(deltaiter), b'cg1 deltaiter()'), |
625 (makebench(iterchunks), 'cg1 getchunks()'), |
672 (makebench(iterchunks), b'cg1 getchunks()'), |
626 (makereadnbytes(8192), 'cg1 read(8k)'), |
673 (makereadnbytes(8192), b'cg1 read(8k)'), |
627 (makereadnbytes(16384), 'cg1 read(16k)'), |
674 (makereadnbytes(16384), b'cg1 read(16k)'), |
628 (makereadnbytes(32768), 'cg1 read(32k)'), |
675 (makereadnbytes(32768), b'cg1 read(32k)'), |
629 (makereadnbytes(131072), 'cg1 read(128k)'), |
676 (makereadnbytes(131072), b'cg1 read(128k)'), |
630 ]) |
677 ]) |
631 elif isinstance(bundle, bundle2.unbundle20): |
678 elif isinstance(bundle, bundle2.unbundle20): |
632 benches.extend([ |
679 benches.extend([ |
633 (makebench(forwardchunks), 'bundle2 forwardchunks()'), |
680 (makebench(forwardchunks), b'bundle2 forwardchunks()'), |
634 (makebench(iterparts), 'bundle2 iterparts()'), |
681 (makebench(iterparts), b'bundle2 iterparts()'), |
635 (makebench(iterpartsseekable), 'bundle2 iterparts() seekable'), |
682 (makebench(iterpartsseekable), b'bundle2 iterparts() seekable'), |
636 (makebench(seek), 'bundle2 part seek()'), |
683 (makebench(seek), b'bundle2 part seek()'), |
637 (makepartreadnbytes(8192), 'bundle2 part read(8k)'), |
684 (makepartreadnbytes(8192), b'bundle2 part read(8k)'), |
638 (makepartreadnbytes(16384), 'bundle2 part read(16k)'), |
685 (makepartreadnbytes(16384), b'bundle2 part read(16k)'), |
639 (makepartreadnbytes(32768), 'bundle2 part read(32k)'), |
686 (makepartreadnbytes(32768), b'bundle2 part read(32k)'), |
640 (makepartreadnbytes(131072), 'bundle2 part read(128k)'), |
687 (makepartreadnbytes(131072), b'bundle2 part read(128k)'), |
641 ]) |
688 ]) |
642 elif isinstance(bundle, streamclone.streamcloneapplier): |
689 elif isinstance(bundle, streamclone.streamcloneapplier): |
643 raise error.Abort('stream clone bundles not supported') |
690 raise error.Abort(b'stream clone bundles not supported') |
644 else: |
691 else: |
645 raise error.Abort('unhandled bundle type: %s' % type(bundle)) |
692 raise error.Abort(b'unhandled bundle type: %s' % type(bundle)) |
646 |
693 |
647 for fn, title in benches: |
694 for fn, title in benches: |
648 timer, fm = gettimer(ui, opts) |
695 timer, fm = gettimer(ui, opts) |
649 timer(fn, title=title) |
696 timer(fn, title=title) |
650 fm.end() |
697 fm.end() |
651 |
698 |
652 @command('perfchangegroupchangelog', formatteropts + |
699 @command(b'perfchangegroupchangelog', formatteropts + |
653 [('', 'version', '02', 'changegroup version'), |
700 [(b'', b'version', b'02', b'changegroup version'), |
654 ('r', 'rev', '', 'revisions to add to changegroup')]) |
701 (b'r', b'rev', b'', b'revisions to add to changegroup')]) |
655 def perfchangegroupchangelog(ui, repo, version='02', rev=None, **opts): |
702 def perfchangegroupchangelog(ui, repo, version=b'02', rev=None, **opts): |
656 """Benchmark producing a changelog group for a changegroup. |
703 """Benchmark producing a changelog group for a changegroup. |
657 |
704 |
658 This measures the time spent processing the changelog during a |
705 This measures the time spent processing the changelog during a |
659 bundle operation. This occurs during `hg bundle` and on a server |
706 bundle operation. This occurs during `hg bundle` and on a server |
660 processing a `getbundle` wire protocol request (handles clones |
707 processing a `getbundle` wire protocol request (handles clones |
661 and pull requests). |
708 and pull requests). |
662 |
709 |
663 By default, all revisions are added to the changegroup. |
710 By default, all revisions are added to the changegroup. |
664 """ |
711 """ |
|
712 opts = _byteskwargs(opts) |
665 cl = repo.changelog |
713 cl = repo.changelog |
666 revs = [cl.lookup(r) for r in repo.revs(rev or 'all()')] |
714 nodes = [cl.lookup(r) for r in repo.revs(rev or b'all()')] |
667 bundler = changegroup.getbundler(version, repo) |
715 bundler = changegroup.getbundler(version, repo) |
668 |
716 |
669 def lookup(node): |
717 def d(): |
670 # The real bundler reads the revision in order to access the |
718 state, chunks = bundler._generatechangelog(cl, nodes) |
671 # manifest node and files list. Do that here. |
719 for chunk in chunks: |
672 cl.read(node) |
|
673 return node |
|
674 |
|
675 def d(): |
|
676 for chunk in bundler.group(revs, cl, lookup): |
|
677 pass |
720 pass |
678 |
721 |
679 timer, fm = gettimer(ui, opts) |
722 timer, fm = gettimer(ui, opts) |
680 timer(d) |
723 |
681 fm.end() |
724 # Terminal printing can interfere with timing. So disable it. |
682 |
725 with ui.configoverride({(b'progress', b'disable'): True}): |
683 @command('perfdirs', formatteropts) |
726 timer(d) |
|
727 |
|
728 fm.end() |
|
729 |
|
730 @command(b'perfdirs', formatteropts) |
684 def perfdirs(ui, repo, **opts): |
731 def perfdirs(ui, repo, **opts): |
|
732 opts = _byteskwargs(opts) |
685 timer, fm = gettimer(ui, opts) |
733 timer, fm = gettimer(ui, opts) |
686 dirstate = repo.dirstate |
734 dirstate = repo.dirstate |
687 'a' in dirstate |
735 b'a' in dirstate |
688 def d(): |
736 def d(): |
689 dirstate.hasdir('a') |
737 dirstate.hasdir(b'a') |
690 del dirstate._map._dirs |
738 del dirstate._map._dirs |
691 timer(d) |
739 timer(d) |
692 fm.end() |
740 fm.end() |
693 |
741 |
694 @command('perfdirstate', formatteropts) |
742 @command(b'perfdirstate', formatteropts) |
695 def perfdirstate(ui, repo, **opts): |
743 def perfdirstate(ui, repo, **opts): |
696 timer, fm = gettimer(ui, opts) |
744 opts = _byteskwargs(opts) |
697 "a" in repo.dirstate |
745 timer, fm = gettimer(ui, opts) |
|
746 b"a" in repo.dirstate |
698 def d(): |
747 def d(): |
699 repo.dirstate.invalidate() |
748 repo.dirstate.invalidate() |
700 "a" in repo.dirstate |
749 b"a" in repo.dirstate |
701 timer(d) |
750 timer(d) |
702 fm.end() |
751 fm.end() |
703 |
752 |
704 @command('perfdirstatedirs', formatteropts) |
753 @command(b'perfdirstatedirs', formatteropts) |
705 def perfdirstatedirs(ui, repo, **opts): |
754 def perfdirstatedirs(ui, repo, **opts): |
706 timer, fm = gettimer(ui, opts) |
755 opts = _byteskwargs(opts) |
707 "a" in repo.dirstate |
756 timer, fm = gettimer(ui, opts) |
708 def d(): |
757 b"a" in repo.dirstate |
709 repo.dirstate.hasdir("a") |
758 def d(): |
|
759 repo.dirstate.hasdir(b"a") |
710 del repo.dirstate._map._dirs |
760 del repo.dirstate._map._dirs |
711 timer(d) |
761 timer(d) |
712 fm.end() |
762 fm.end() |
713 |
763 |
714 @command('perfdirstatefoldmap', formatteropts) |
764 @command(b'perfdirstatefoldmap', formatteropts) |
715 def perfdirstatefoldmap(ui, repo, **opts): |
765 def perfdirstatefoldmap(ui, repo, **opts): |
|
766 opts = _byteskwargs(opts) |
716 timer, fm = gettimer(ui, opts) |
767 timer, fm = gettimer(ui, opts) |
717 dirstate = repo.dirstate |
768 dirstate = repo.dirstate |
718 'a' in dirstate |
769 b'a' in dirstate |
719 def d(): |
770 def d(): |
720 dirstate._map.filefoldmap.get('a') |
771 dirstate._map.filefoldmap.get(b'a') |
721 del dirstate._map.filefoldmap |
772 del dirstate._map.filefoldmap |
722 timer(d) |
773 timer(d) |
723 fm.end() |
774 fm.end() |
724 |
775 |
725 @command('perfdirfoldmap', formatteropts) |
776 @command(b'perfdirfoldmap', formatteropts) |
726 def perfdirfoldmap(ui, repo, **opts): |
777 def perfdirfoldmap(ui, repo, **opts): |
|
778 opts = _byteskwargs(opts) |
727 timer, fm = gettimer(ui, opts) |
779 timer, fm = gettimer(ui, opts) |
728 dirstate = repo.dirstate |
780 dirstate = repo.dirstate |
729 'a' in dirstate |
781 b'a' in dirstate |
730 def d(): |
782 def d(): |
731 dirstate._map.dirfoldmap.get('a') |
783 dirstate._map.dirfoldmap.get(b'a') |
732 del dirstate._map.dirfoldmap |
784 del dirstate._map.dirfoldmap |
733 del dirstate._map._dirs |
785 del dirstate._map._dirs |
734 timer(d) |
786 timer(d) |
735 fm.end() |
787 fm.end() |
736 |
788 |
737 @command('perfdirstatewrite', formatteropts) |
789 @command(b'perfdirstatewrite', formatteropts) |
738 def perfdirstatewrite(ui, repo, **opts): |
790 def perfdirstatewrite(ui, repo, **opts): |
|
791 opts = _byteskwargs(opts) |
739 timer, fm = gettimer(ui, opts) |
792 timer, fm = gettimer(ui, opts) |
740 ds = repo.dirstate |
793 ds = repo.dirstate |
741 "a" in ds |
794 b"a" in ds |
742 def d(): |
795 def d(): |
743 ds._dirty = True |
796 ds._dirty = True |
744 ds.write(repo.currenttransaction()) |
797 ds.write(repo.currenttransaction()) |
745 timer(d) |
798 timer(d) |
746 fm.end() |
799 fm.end() |
747 |
800 |
748 @command('perfmergecalculate', |
801 @command(b'perfmergecalculate', |
749 [('r', 'rev', '.', 'rev to merge against')] + formatteropts) |
802 [(b'r', b'rev', b'.', b'rev to merge against')] + formatteropts) |
750 def perfmergecalculate(ui, repo, rev, **opts): |
803 def perfmergecalculate(ui, repo, rev, **opts): |
|
804 opts = _byteskwargs(opts) |
751 timer, fm = gettimer(ui, opts) |
805 timer, fm = gettimer(ui, opts) |
752 wctx = repo[None] |
806 wctx = repo[None] |
753 rctx = scmutil.revsingle(repo, rev, rev) |
807 rctx = scmutil.revsingle(repo, rev, rev) |
754 ancestor = wctx.ancestor(rctx) |
808 ancestor = wctx.ancestor(rctx) |
755 # we don't want working dir files to be stat'd in the benchmark, so prime |
809 # we don't want working dir files to be stat'd in the benchmark, so prime |
761 merge.calculateupdates(repo, wctx, rctx, [ancestor], False, False, |
815 merge.calculateupdates(repo, wctx, rctx, [ancestor], False, False, |
762 acceptremote=True, followcopies=True) |
816 acceptremote=True, followcopies=True) |
763 timer(d) |
817 timer(d) |
764 fm.end() |
818 fm.end() |
765 |
819 |
766 @command('perfpathcopies', [], "REV REV") |
820 @command(b'perfpathcopies', [], b"REV REV") |
767 def perfpathcopies(ui, repo, rev1, rev2, **opts): |
821 def perfpathcopies(ui, repo, rev1, rev2, **opts): |
|
822 opts = _byteskwargs(opts) |
768 timer, fm = gettimer(ui, opts) |
823 timer, fm = gettimer(ui, opts) |
769 ctx1 = scmutil.revsingle(repo, rev1, rev1) |
824 ctx1 = scmutil.revsingle(repo, rev1, rev1) |
770 ctx2 = scmutil.revsingle(repo, rev2, rev2) |
825 ctx2 = scmutil.revsingle(repo, rev2, rev2) |
771 def d(): |
826 def d(): |
772 copies.pathcopies(ctx1, ctx2) |
827 copies.pathcopies(ctx1, ctx2) |
773 timer(d) |
828 timer(d) |
774 fm.end() |
829 fm.end() |
775 |
830 |
776 @command('perfphases', |
831 @command(b'perfphases', |
777 [('', 'full', False, 'include file reading time too'), |
832 [(b'', b'full', False, b'include file reading time too'), |
778 ], "") |
833 ], b"") |
779 def perfphases(ui, repo, **opts): |
834 def perfphases(ui, repo, **opts): |
780 """benchmark phasesets computation""" |
835 """benchmark phasesets computation""" |
|
836 opts = _byteskwargs(opts) |
781 timer, fm = gettimer(ui, opts) |
837 timer, fm = gettimer(ui, opts) |
782 _phases = repo._phasecache |
838 _phases = repo._phasecache |
783 full = opts.get('full') |
839 full = opts.get(b'full') |
784 def d(): |
840 def d(): |
785 phases = _phases |
841 phases = _phases |
786 if full: |
842 if full: |
787 clearfilecache(repo, '_phasecache') |
843 clearfilecache(repo, b'_phasecache') |
788 phases = repo._phasecache |
844 phases = repo._phasecache |
789 phases.invalidate() |
845 phases.invalidate() |
790 phases.loadphaserevs(repo) |
846 phases.loadphaserevs(repo) |
791 timer(d) |
847 timer(d) |
792 fm.end() |
848 fm.end() |
793 |
849 |
794 @command('perfphasesremote', |
850 @command(b'perfphasesremote', |
795 [], "[DEST]") |
851 [], b"[DEST]") |
796 def perfphasesremote(ui, repo, dest=None, **opts): |
852 def perfphasesremote(ui, repo, dest=None, **opts): |
797 """benchmark time needed to analyse phases of the remote server""" |
853 """benchmark time needed to analyse phases of the remote server""" |
798 from mercurial.node import ( |
854 from mercurial.node import ( |
799 bin, |
855 bin, |
800 ) |
856 ) |
801 from mercurial import ( |
857 from mercurial import ( |
802 exchange, |
858 exchange, |
803 hg, |
859 hg, |
804 phases, |
860 phases, |
805 ) |
861 ) |
806 timer, fm = gettimer(ui, opts) |
862 opts = _byteskwargs(opts) |
807 |
863 timer, fm = gettimer(ui, opts) |
808 path = ui.paths.getpath(dest, default=('default-push', 'default')) |
864 |
|
865 path = ui.paths.getpath(dest, default=(b'default-push', b'default')) |
809 if not path: |
866 if not path: |
810 raise error.Abort(('default repository not configured!'), |
867 raise error.Abort((b'default repository not configured!'), |
811 hint=("see 'hg help config.paths'")) |
868 hint=(b"see 'hg help config.paths'")) |
812 dest = path.pushloc or path.loc |
869 dest = path.pushloc or path.loc |
813 branches = (path.branch, opts.get('branch') or []) |
870 branches = (path.branch, opts.get(b'branch') or []) |
814 ui.status(('analysing phase of %s\n') % util.hidepassword(dest)) |
871 ui.status((b'analysing phase of %s\n') % util.hidepassword(dest)) |
815 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev')) |
872 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev')) |
816 other = hg.peer(repo, opts, dest) |
873 other = hg.peer(repo, opts, dest) |
817 |
874 |
818 # easier to perform discovery through the operation |
875 # easier to perform discovery through the operation |
819 op = exchange.pushoperation(repo, other) |
876 op = exchange.pushoperation(repo, other) |
820 exchange._pushdiscoverychangeset(op) |
877 exchange._pushdiscoverychangeset(op) |
821 |
878 |
822 remotesubset = op.fallbackheads |
879 remotesubset = op.fallbackheads |
823 |
880 |
824 with other.commandexecutor() as e: |
881 with other.commandexecutor() as e: |
825 remotephases = e.callcommand('listkeys', |
882 remotephases = e.callcommand(b'listkeys', |
826 {'namespace': 'phases'}).result() |
883 {b'namespace': b'phases'}).result() |
827 del other |
884 del other |
828 publishing = remotephases.get('publishing', False) |
885 publishing = remotephases.get(b'publishing', False) |
829 if publishing: |
886 if publishing: |
830 ui.status(('publishing: yes\n')) |
887 ui.status((b'publishing: yes\n')) |
831 else: |
888 else: |
832 ui.status(('publishing: no\n')) |
889 ui.status((b'publishing: no\n')) |
833 |
890 |
834 nodemap = repo.changelog.nodemap |
891 nodemap = repo.changelog.nodemap |
835 nonpublishroots = 0 |
892 nonpublishroots = 0 |
836 for nhex, phase in remotephases.iteritems(): |
893 for nhex, phase in remotephases.iteritems(): |
837 if nhex == 'publishing': # ignore data related to publish option |
894 if nhex == b'publishing': # ignore data related to publish option |
838 continue |
895 continue |
839 node = bin(nhex) |
896 node = bin(nhex) |
840 if node in nodemap and int(phase): |
897 if node in nodemap and int(phase): |
841 nonpublishroots += 1 |
898 nonpublishroots += 1 |
842 ui.status(('number of roots: %d\n') % len(remotephases)) |
899 ui.status((b'number of roots: %d\n') % len(remotephases)) |
843 ui.status(('number of known non public roots: %d\n') % nonpublishroots) |
900 ui.status((b'number of known non public roots: %d\n') % nonpublishroots) |
844 def d(): |
901 def d(): |
845 phases.remotephasessummary(repo, |
902 phases.remotephasessummary(repo, |
846 remotesubset, |
903 remotesubset, |
847 remotephases) |
904 remotephases) |
848 timer(d) |
905 timer(d) |
849 fm.end() |
906 fm.end() |
850 |
907 |
851 @command('perfmanifest', [], 'REV') |
908 @command(b'perfmanifest',[ |
852 def perfmanifest(ui, repo, rev, **opts): |
909 (b'm', b'manifest-rev', False, b'Look up a manifest node revision'), |
|
910 (b'', b'clear-disk', False, b'clear on-disk caches too'), |
|
911 ] + formatteropts, b'REV|NODE') |
|
912 def perfmanifest(ui, repo, rev, manifest_rev=False, clear_disk=False, **opts): |
853 """benchmark the time to read a manifest from disk and return a usable |
913 """benchmark the time to read a manifest from disk and return a usable |
854 dict-like object |
914 dict-like object |
855 |
915 |
856 Manifest caches are cleared before retrieval.""" |
916 Manifest caches are cleared before retrieval.""" |
857 timer, fm = gettimer(ui, opts) |
917 opts = _byteskwargs(opts) |
858 ctx = scmutil.revsingle(repo, rev, rev) |
918 timer, fm = gettimer(ui, opts) |
859 t = ctx.manifestnode() |
919 if not manifest_rev: |
860 def d(): |
920 ctx = scmutil.revsingle(repo, rev, rev) |
861 repo.manifestlog.clearcaches() |
921 t = ctx.manifestnode() |
|
922 else: |
|
923 from mercurial.node import bin |
|
924 |
|
925 if len(rev) == 40: |
|
926 t = bin(rev) |
|
927 else: |
|
928 try: |
|
929 rev = int(rev) |
|
930 |
|
931 if util.safehasattr(repo.manifestlog, b'getstorage'): |
|
932 t = repo.manifestlog.getstorage(b'').node(rev) |
|
933 else: |
|
934 t = repo.manifestlog._revlog.lookup(rev) |
|
935 except ValueError: |
|
936 raise error.Abort(b'manifest revision must be integer or full ' |
|
937 b'node') |
|
938 def d(): |
|
939 repo.manifestlog.clearcaches(clear_persisted_data=clear_disk) |
862 repo.manifestlog[t].read() |
940 repo.manifestlog[t].read() |
863 timer(d) |
941 timer(d) |
864 fm.end() |
942 fm.end() |
865 |
943 |
866 @command('perfchangeset', formatteropts) |
944 @command(b'perfchangeset', formatteropts) |
867 def perfchangeset(ui, repo, rev, **opts): |
945 def perfchangeset(ui, repo, rev, **opts): |
|
946 opts = _byteskwargs(opts) |
868 timer, fm = gettimer(ui, opts) |
947 timer, fm = gettimer(ui, opts) |
869 n = scmutil.revsingle(repo, rev).node() |
948 n = scmutil.revsingle(repo, rev).node() |
870 def d(): |
949 def d(): |
871 repo.changelog.read(n) |
950 repo.changelog.read(n) |
872 #repo.changelog._cache = None |
951 #repo.changelog._cache = None |
873 timer(d) |
952 timer(d) |
874 fm.end() |
953 fm.end() |
875 |
954 |
876 @command('perfindex', formatteropts) |
955 @command(b'perfindex', formatteropts) |
877 def perfindex(ui, repo, **opts): |
956 def perfindex(ui, repo, **opts): |
878 import mercurial.revlog |
957 import mercurial.revlog |
|
958 opts = _byteskwargs(opts) |
879 timer, fm = gettimer(ui, opts) |
959 timer, fm = gettimer(ui, opts) |
880 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg |
960 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg |
881 n = repo["tip"].node() |
961 n = repo[b"tip"].node() |
882 svfs = getsvfs(repo) |
962 svfs = getsvfs(repo) |
883 def d(): |
963 def d(): |
884 cl = mercurial.revlog.revlog(svfs, "00changelog.i") |
964 cl = mercurial.revlog.revlog(svfs, b"00changelog.i") |
885 cl.rev(n) |
965 cl.rev(n) |
886 timer(d) |
966 timer(d) |
887 fm.end() |
967 fm.end() |
888 |
968 |
889 @command('perfstartup', formatteropts) |
969 @command(b'perfstartup', formatteropts) |
890 def perfstartup(ui, repo, **opts): |
970 def perfstartup(ui, repo, **opts): |
891 timer, fm = gettimer(ui, opts) |
971 opts = _byteskwargs(opts) |
892 cmd = sys.argv[0] |
972 timer, fm = gettimer(ui, opts) |
893 def d(): |
973 def d(): |
894 if os.name != 'nt': |
974 if os.name != r'nt': |
895 os.system("HGRCPATH= %s version -q > /dev/null" % cmd) |
975 os.system(b"HGRCPATH= %s version -q > /dev/null" % |
|
976 fsencode(sys.argv[0])) |
896 else: |
977 else: |
897 os.environ['HGRCPATH'] = ' ' |
978 os.environ[r'HGRCPATH'] = r' ' |
898 os.system("%s version -q > NUL" % cmd) |
979 os.system(r"%s version -q > NUL" % sys.argv[0]) |
899 timer(d) |
980 timer(d) |
900 fm.end() |
981 fm.end() |
901 |
982 |
902 @command('perfparents', formatteropts) |
983 @command(b'perfparents', formatteropts) |
903 def perfparents(ui, repo, **opts): |
984 def perfparents(ui, repo, **opts): |
|
985 opts = _byteskwargs(opts) |
904 timer, fm = gettimer(ui, opts) |
986 timer, fm = gettimer(ui, opts) |
905 # control the number of commits perfparents iterates over |
987 # control the number of commits perfparents iterates over |
906 # experimental config: perf.parentscount |
988 # experimental config: perf.parentscount |
907 count = getint(ui, "perf", "parentscount", 1000) |
989 count = getint(ui, b"perf", b"parentscount", 1000) |
908 if len(repo.changelog) < count: |
990 if len(repo.changelog) < count: |
909 raise error.Abort("repo needs %d commits for this test" % count) |
991 raise error.Abort(b"repo needs %d commits for this test" % count) |
910 repo = repo.unfiltered() |
992 repo = repo.unfiltered() |
911 nl = [repo.changelog.node(i) for i in xrange(count)] |
993 nl = [repo.changelog.node(i) for i in _xrange(count)] |
912 def d(): |
994 def d(): |
913 for n in nl: |
995 for n in nl: |
914 repo.changelog.parents(n) |
996 repo.changelog.parents(n) |
915 timer(d) |
997 timer(d) |
916 fm.end() |
998 fm.end() |
917 |
999 |
918 @command('perfctxfiles', formatteropts) |
1000 @command(b'perfctxfiles', formatteropts) |
919 def perfctxfiles(ui, repo, x, **opts): |
1001 def perfctxfiles(ui, repo, x, **opts): |
|
1002 opts = _byteskwargs(opts) |
920 x = int(x) |
1003 x = int(x) |
921 timer, fm = gettimer(ui, opts) |
1004 timer, fm = gettimer(ui, opts) |
922 def d(): |
1005 def d(): |
923 len(repo[x].files()) |
1006 len(repo[x].files()) |
924 timer(d) |
1007 timer(d) |
925 fm.end() |
1008 fm.end() |
926 |
1009 |
927 @command('perfrawfiles', formatteropts) |
1010 @command(b'perfrawfiles', formatteropts) |
928 def perfrawfiles(ui, repo, x, **opts): |
1011 def perfrawfiles(ui, repo, x, **opts): |
|
1012 opts = _byteskwargs(opts) |
929 x = int(x) |
1013 x = int(x) |
930 timer, fm = gettimer(ui, opts) |
1014 timer, fm = gettimer(ui, opts) |
931 cl = repo.changelog |
1015 cl = repo.changelog |
932 def d(): |
1016 def d(): |
933 len(cl.read(x)[3]) |
1017 len(cl.read(x)[3]) |
934 timer(d) |
1018 timer(d) |
935 fm.end() |
1019 fm.end() |
936 |
1020 |
937 @command('perflookup', formatteropts) |
1021 @command(b'perflookup', formatteropts) |
938 def perflookup(ui, repo, rev, **opts): |
1022 def perflookup(ui, repo, rev, **opts): |
|
1023 opts = _byteskwargs(opts) |
939 timer, fm = gettimer(ui, opts) |
1024 timer, fm = gettimer(ui, opts) |
940 timer(lambda: len(repo.lookup(rev))) |
1025 timer(lambda: len(repo.lookup(rev))) |
941 fm.end() |
1026 fm.end() |
942 |
1027 |
943 @command('perfrevrange', formatteropts) |
1028 @command(b'perflinelogedits', |
|
1029 [(b'n', b'edits', 10000, b'number of edits'), |
|
1030 (b'', b'max-hunk-lines', 10, b'max lines in a hunk'), |
|
1031 ], norepo=True) |
|
1032 def perflinelogedits(ui, **opts): |
|
1033 from mercurial import linelog |
|
1034 |
|
1035 opts = _byteskwargs(opts) |
|
1036 |
|
1037 edits = opts[b'edits'] |
|
1038 maxhunklines = opts[b'max_hunk_lines'] |
|
1039 |
|
1040 maxb1 = 100000 |
|
1041 random.seed(0) |
|
1042 randint = random.randint |
|
1043 currentlines = 0 |
|
1044 arglist = [] |
|
1045 for rev in _xrange(edits): |
|
1046 a1 = randint(0, currentlines) |
|
1047 a2 = randint(a1, min(currentlines, a1 + maxhunklines)) |
|
1048 b1 = randint(0, maxb1) |
|
1049 b2 = randint(b1, b1 + maxhunklines) |
|
1050 currentlines += (b2 - b1) - (a2 - a1) |
|
1051 arglist.append((rev, a1, a2, b1, b2)) |
|
1052 |
|
1053 def d(): |
|
1054 ll = linelog.linelog() |
|
1055 for args in arglist: |
|
1056 ll.replacelines(*args) |
|
1057 |
|
1058 timer, fm = gettimer(ui, opts) |
|
1059 timer(d) |
|
1060 fm.end() |
|
1061 |
|
1062 @command(b'perfrevrange', formatteropts) |
944 def perfrevrange(ui, repo, *specs, **opts): |
1063 def perfrevrange(ui, repo, *specs, **opts): |
|
1064 opts = _byteskwargs(opts) |
945 timer, fm = gettimer(ui, opts) |
1065 timer, fm = gettimer(ui, opts) |
946 revrange = scmutil.revrange |
1066 revrange = scmutil.revrange |
947 timer(lambda: len(revrange(repo, specs))) |
1067 timer(lambda: len(revrange(repo, specs))) |
948 fm.end() |
1068 fm.end() |
949 |
1069 |
950 @command('perfnodelookup', formatteropts) |
1070 @command(b'perfnodelookup', formatteropts) |
951 def perfnodelookup(ui, repo, rev, **opts): |
1071 def perfnodelookup(ui, repo, rev, **opts): |
|
1072 opts = _byteskwargs(opts) |
952 timer, fm = gettimer(ui, opts) |
1073 timer, fm = gettimer(ui, opts) |
953 import mercurial.revlog |
1074 import mercurial.revlog |
954 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg |
1075 mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg |
955 n = scmutil.revsingle(repo, rev).node() |
1076 n = scmutil.revsingle(repo, rev).node() |
956 cl = mercurial.revlog.revlog(getsvfs(repo), "00changelog.i") |
1077 cl = mercurial.revlog.revlog(getsvfs(repo), b"00changelog.i") |
957 def d(): |
1078 def d(): |
958 cl.rev(n) |
1079 cl.rev(n) |
959 clearcaches(cl) |
1080 clearcaches(cl) |
960 timer(d) |
1081 timer(d) |
961 fm.end() |
1082 fm.end() |
962 |
1083 |
963 @command('perflog', |
1084 @command(b'perflog', |
964 [('', 'rename', False, 'ask log to follow renames')] + formatteropts) |
1085 [(b'', b'rename', False, b'ask log to follow renames') |
|
1086 ] + formatteropts) |
965 def perflog(ui, repo, rev=None, **opts): |
1087 def perflog(ui, repo, rev=None, **opts): |
|
1088 opts = _byteskwargs(opts) |
966 if rev is None: |
1089 if rev is None: |
967 rev=[] |
1090 rev=[] |
968 timer, fm = gettimer(ui, opts) |
1091 timer, fm = gettimer(ui, opts) |
969 ui.pushbuffer() |
1092 ui.pushbuffer() |
970 timer(lambda: commands.log(ui, repo, rev=rev, date='', user='', |
1093 timer(lambda: commands.log(ui, repo, rev=rev, date=b'', user=b'', |
971 copies=opts.get('rename'))) |
1094 copies=opts.get(b'rename'))) |
972 ui.popbuffer() |
1095 ui.popbuffer() |
973 fm.end() |
1096 fm.end() |
974 |
1097 |
975 @command('perfmoonwalk', formatteropts) |
1098 @command(b'perfmoonwalk', formatteropts) |
976 def perfmoonwalk(ui, repo, **opts): |
1099 def perfmoonwalk(ui, repo, **opts): |
977 """benchmark walking the changelog backwards |
1100 """benchmark walking the changelog backwards |
978 |
1101 |
979 This also loads the changelog data for each revision in the changelog. |
1102 This also loads the changelog data for each revision in the changelog. |
980 """ |
1103 """ |
|
1104 opts = _byteskwargs(opts) |
981 timer, fm = gettimer(ui, opts) |
1105 timer, fm = gettimer(ui, opts) |
982 def moonwalk(): |
1106 def moonwalk(): |
983 for i in xrange(len(repo), -1, -1): |
1107 for i in repo.changelog.revs(start=(len(repo) - 1), stop=-1): |
984 ctx = repo[i] |
1108 ctx = repo[i] |
985 ctx.branch() # read changelog data (in addition to the index) |
1109 ctx.branch() # read changelog data (in addition to the index) |
986 timer(moonwalk) |
1110 timer(moonwalk) |
987 fm.end() |
1111 fm.end() |
988 |
1112 |
989 @command('perftemplating', |
1113 @command(b'perftemplating', |
990 [('r', 'rev', [], 'revisions to run the template on'), |
1114 [(b'r', b'rev', [], b'revisions to run the template on'), |
991 ] + formatteropts) |
1115 ] + formatteropts) |
992 def perftemplating(ui, repo, testedtemplate=None, **opts): |
1116 def perftemplating(ui, repo, testedtemplate=None, **opts): |
993 """test the rendering time of a given template""" |
1117 """test the rendering time of a given template""" |
994 if makelogtemplater is None: |
1118 if makelogtemplater is None: |
995 raise error.Abort(("perftemplating not available with this Mercurial"), |
1119 raise error.Abort((b"perftemplating not available with this Mercurial"), |
996 hint="use 4.3 or later") |
1120 hint=b"use 4.3 or later") |
|
1121 |
|
1122 opts = _byteskwargs(opts) |
997 |
1123 |
998 nullui = ui.copy() |
1124 nullui = ui.copy() |
999 nullui.fout = open(os.devnull, 'wb') |
1125 nullui.fout = open(os.devnull, r'wb') |
1000 nullui.disablepager() |
1126 nullui.disablepager() |
1001 revs = opts.get('rev') |
1127 revs = opts.get(b'rev') |
1002 if not revs: |
1128 if not revs: |
1003 revs = ['all()'] |
1129 revs = [b'all()'] |
1004 revs = list(scmutil.revrange(repo, revs)) |
1130 revs = list(scmutil.revrange(repo, revs)) |
1005 |
1131 |
1006 defaulttemplate = ('{date|shortdate} [{rev}:{node|short}]' |
1132 defaulttemplate = (b'{date|shortdate} [{rev}:{node|short}]' |
1007 ' {author|person}: {desc|firstline}\n') |
1133 b' {author|person}: {desc|firstline}\n') |
1008 if testedtemplate is None: |
1134 if testedtemplate is None: |
1009 testedtemplate = defaulttemplate |
1135 testedtemplate = defaulttemplate |
1010 displayer = makelogtemplater(nullui, repo, testedtemplate) |
1136 displayer = makelogtemplater(nullui, repo, testedtemplate) |
1011 def format(): |
1137 def format(): |
1012 for r in revs: |
1138 for r in revs: |
1232 |
1373 |
1233 def d(): |
1374 def d(): |
1234 for left, right in textpairs: |
1375 for left, right in textpairs: |
1235 # The date strings don't matter, so we pass empty strings. |
1376 # The date strings don't matter, so we pass empty strings. |
1236 headerlines, hunks = mdiff.unidiff( |
1377 headerlines, hunks = mdiff.unidiff( |
1237 left, '', right, '', 'left', 'right', binary=False) |
1378 left, b'', right, b'', b'left', b'right', binary=False) |
1238 # consume iterators in roughly the way patch.py does |
1379 # consume iterators in roughly the way patch.py does |
1239 b'\n'.join(headerlines) |
1380 b'\n'.join(headerlines) |
1240 b''.join(sum((list(hlines) for hrange, hlines in hunks), [])) |
1381 b''.join(sum((list(hlines) for hrange, hlines in hunks), [])) |
1241 timer, fm = gettimer(ui, opts) |
1382 timer, fm = gettimer(ui, opts) |
1242 timer(d) |
1383 timer(d) |
1243 fm.end() |
1384 fm.end() |
1244 |
1385 |
1245 @command('perfdiffwd', formatteropts) |
1386 @command(b'perfdiffwd', formatteropts) |
1246 def perfdiffwd(ui, repo, **opts): |
1387 def perfdiffwd(ui, repo, **opts): |
1247 """Profile diff of working directory changes""" |
1388 """Profile diff of working directory changes""" |
|
1389 opts = _byteskwargs(opts) |
1248 timer, fm = gettimer(ui, opts) |
1390 timer, fm = gettimer(ui, opts) |
1249 options = { |
1391 options = { |
1250 'w': 'ignore_all_space', |
1392 'w': 'ignore_all_space', |
1251 'b': 'ignore_space_change', |
1393 'b': 'ignore_space_change', |
1252 'B': 'ignore_blank_lines', |
1394 'B': 'ignore_blank_lines', |
1253 } |
1395 } |
1254 |
1396 |
1255 for diffopt in ('', 'w', 'b', 'B', 'wB'): |
1397 for diffopt in ('', 'w', 'b', 'B', 'wB'): |
1256 opts = dict((options[c], '1') for c in diffopt) |
1398 opts = dict((options[c], b'1') for c in diffopt) |
1257 def d(): |
1399 def d(): |
1258 ui.pushbuffer() |
1400 ui.pushbuffer() |
1259 commands.diff(ui, repo, **opts) |
1401 commands.diff(ui, repo, **opts) |
1260 ui.popbuffer() |
1402 ui.popbuffer() |
1261 title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none') |
1403 diffopt = diffopt.encode('ascii') |
|
1404 title = b'diffopts: %s' % (diffopt and (b'-' + diffopt) or b'none') |
1262 timer(d, title) |
1405 timer(d, title) |
1263 fm.end() |
1406 fm.end() |
1264 |
1407 |
1265 @command('perfrevlogindex', revlogopts + formatteropts, |
1408 @command(b'perfrevlogindex', revlogopts + formatteropts, |
1266 '-c|-m|FILE') |
1409 b'-c|-m|FILE') |
1267 def perfrevlogindex(ui, repo, file_=None, **opts): |
1410 def perfrevlogindex(ui, repo, file_=None, **opts): |
1268 """Benchmark operations against a revlog index. |
1411 """Benchmark operations against a revlog index. |
1269 |
1412 |
1270 This tests constructing a revlog instance, reading index data, |
1413 This tests constructing a revlog instance, reading index data, |
1271 parsing index data, and performing various operations related to |
1414 parsing index data, and performing various operations related to |
1272 index data. |
1415 index data. |
1273 """ |
1416 """ |
1274 |
1417 |
1275 rl = cmdutil.openrevlog(repo, 'perfrevlogindex', file_, opts) |
1418 opts = _byteskwargs(opts) |
|
1419 |
|
1420 rl = cmdutil.openrevlog(repo, b'perfrevlogindex', file_, opts) |
1276 |
1421 |
1277 opener = getattr(rl, 'opener') # trick linter |
1422 opener = getattr(rl, 'opener') # trick linter |
1278 indexfile = rl.indexfile |
1423 indexfile = rl.indexfile |
1279 data = opener.read(indexfile) |
1424 data = opener.read(indexfile) |
1280 |
1425 |
1281 header = struct.unpack('>I', data[0:4])[0] |
1426 header = struct.unpack(b'>I', data[0:4])[0] |
1282 version = header & 0xFFFF |
1427 version = header & 0xFFFF |
1283 if version == 1: |
1428 if version == 1: |
1284 revlogio = revlog.revlogio() |
1429 revlogio = revlog.revlogio() |
1285 inline = header & (1 << 16) |
1430 inline = header & (1 << 16) |
1286 else: |
1431 else: |
1287 raise error.Abort(('unsupported revlog version: %d') % version) |
1432 raise error.Abort((b'unsupported revlog version: %d') % version) |
1288 |
1433 |
1289 rllen = len(rl) |
1434 rllen = len(rl) |
1290 |
1435 |
1291 node0 = rl.node(0) |
1436 node0 = rl.node(0) |
1292 node25 = rl.node(rllen // 4) |
1437 node25 = rl.node(rllen // 4) |
1342 nodemap[node] |
1487 nodemap[node] |
1343 except error.RevlogError: |
1488 except error.RevlogError: |
1344 pass |
1489 pass |
1345 |
1490 |
1346 benches = [ |
1491 benches = [ |
1347 (constructor, 'revlog constructor'), |
1492 (constructor, b'revlog constructor'), |
1348 (read, 'read'), |
1493 (read, b'read'), |
1349 (parseindex, 'create index object'), |
1494 (parseindex, b'create index object'), |
1350 (lambda: getentry(0), 'retrieve index entry for rev 0'), |
1495 (lambda: getentry(0), b'retrieve index entry for rev 0'), |
1351 (lambda: resolvenode('a' * 20), 'look up missing node'), |
1496 (lambda: resolvenode(b'a' * 20), b'look up missing node'), |
1352 (lambda: resolvenode(node0), 'look up node at rev 0'), |
1497 (lambda: resolvenode(node0), b'look up node at rev 0'), |
1353 (lambda: resolvenode(node25), 'look up node at 1/4 len'), |
1498 (lambda: resolvenode(node25), b'look up node at 1/4 len'), |
1354 (lambda: resolvenode(node50), 'look up node at 1/2 len'), |
1499 (lambda: resolvenode(node50), b'look up node at 1/2 len'), |
1355 (lambda: resolvenode(node75), 'look up node at 3/4 len'), |
1500 (lambda: resolvenode(node75), b'look up node at 3/4 len'), |
1356 (lambda: resolvenode(node100), 'look up node at tip'), |
1501 (lambda: resolvenode(node100), b'look up node at tip'), |
1357 # 2x variation is to measure caching impact. |
1502 # 2x variation is to measure caching impact. |
1358 (lambda: resolvenodes(allnodes), |
1503 (lambda: resolvenodes(allnodes), |
1359 'look up all nodes (forward)'), |
1504 b'look up all nodes (forward)'), |
1360 (lambda: resolvenodes(allnodes, 2), |
1505 (lambda: resolvenodes(allnodes, 2), |
1361 'look up all nodes 2x (forward)'), |
1506 b'look up all nodes 2x (forward)'), |
1362 (lambda: resolvenodes(allnodesrev), |
1507 (lambda: resolvenodes(allnodesrev), |
1363 'look up all nodes (reverse)'), |
1508 b'look up all nodes (reverse)'), |
1364 (lambda: resolvenodes(allnodesrev, 2), |
1509 (lambda: resolvenodes(allnodesrev, 2), |
1365 'look up all nodes 2x (reverse)'), |
1510 b'look up all nodes 2x (reverse)'), |
1366 (lambda: getentries(allrevs), |
1511 (lambda: getentries(allrevs), |
1367 'retrieve all index entries (forward)'), |
1512 b'retrieve all index entries (forward)'), |
1368 (lambda: getentries(allrevs, 2), |
1513 (lambda: getentries(allrevs, 2), |
1369 'retrieve all index entries 2x (forward)'), |
1514 b'retrieve all index entries 2x (forward)'), |
1370 (lambda: getentries(allrevsrev), |
1515 (lambda: getentries(allrevsrev), |
1371 'retrieve all index entries (reverse)'), |
1516 b'retrieve all index entries (reverse)'), |
1372 (lambda: getentries(allrevsrev, 2), |
1517 (lambda: getentries(allrevsrev, 2), |
1373 'retrieve all index entries 2x (reverse)'), |
1518 b'retrieve all index entries 2x (reverse)'), |
1374 ] |
1519 ] |
1375 |
1520 |
1376 for fn, title in benches: |
1521 for fn, title in benches: |
1377 timer, fm = gettimer(ui, opts) |
1522 timer, fm = gettimer(ui, opts) |
1378 timer(fn, title=title) |
1523 timer(fn, title=title) |
1379 fm.end() |
1524 fm.end() |
1380 |
1525 |
1381 @command('perfrevlogrevisions', revlogopts + formatteropts + |
1526 @command(b'perfrevlogrevisions', revlogopts + formatteropts + |
1382 [('d', 'dist', 100, 'distance between the revisions'), |
1527 [(b'd', b'dist', 100, b'distance between the revisions'), |
1383 ('s', 'startrev', 0, 'revision to start reading at'), |
1528 (b's', b'startrev', 0, b'revision to start reading at'), |
1384 ('', 'reverse', False, 'read in reverse')], |
1529 (b'', b'reverse', False, b'read in reverse')], |
1385 '-c|-m|FILE') |
1530 b'-c|-m|FILE') |
1386 def perfrevlogrevisions(ui, repo, file_=None, startrev=0, reverse=False, |
1531 def perfrevlogrevisions(ui, repo, file_=None, startrev=0, reverse=False, |
1387 **opts): |
1532 **opts): |
1388 """Benchmark reading a series of revisions from a revlog. |
1533 """Benchmark reading a series of revisions from a revlog. |
1389 |
1534 |
1390 By default, we read every ``-d/--dist`` revision from 0 to tip of |
1535 By default, we read every ``-d/--dist`` revision from 0 to tip of |
1391 the specified revlog. |
1536 the specified revlog. |
1392 |
1537 |
1393 The start revision can be defined via ``-s/--startrev``. |
1538 The start revision can be defined via ``-s/--startrev``. |
1394 """ |
1539 """ |
1395 rl = cmdutil.openrevlog(repo, 'perfrevlogrevisions', file_, opts) |
1540 opts = _byteskwargs(opts) |
|
1541 |
|
1542 rl = cmdutil.openrevlog(repo, b'perfrevlogrevisions', file_, opts) |
1396 rllen = getlen(ui)(rl) |
1543 rllen = getlen(ui)(rl) |
|
1544 |
|
1545 if startrev < 0: |
|
1546 startrev = rllen + startrev |
1397 |
1547 |
1398 def d(): |
1548 def d(): |
1399 rl.clearcaches() |
1549 rl.clearcaches() |
1400 |
1550 |
1401 beginrev = startrev |
1551 beginrev = startrev |
1402 endrev = rllen |
1552 endrev = rllen |
1403 dist = opts['dist'] |
1553 dist = opts[b'dist'] |
1404 |
1554 |
1405 if reverse: |
1555 if reverse: |
1406 beginrev, endrev = endrev, beginrev |
1556 beginrev, endrev = endrev, beginrev |
1407 dist = -1 * dist |
1557 dist = -1 * dist |
1408 |
1558 |
1409 for x in xrange(beginrev, endrev, dist): |
1559 for x in _xrange(beginrev, endrev, dist): |
1410 # Old revisions don't support passing int. |
1560 # Old revisions don't support passing int. |
1411 n = rl.node(x) |
1561 n = rl.node(x) |
1412 rl.revision(n) |
1562 rl.revision(n) |
1413 |
1563 |
1414 timer, fm = gettimer(ui, opts) |
1564 timer, fm = gettimer(ui, opts) |
1415 timer(d) |
1565 timer(d) |
1416 fm.end() |
1566 fm.end() |
1417 |
1567 |
1418 @command('perfrevlogchunks', revlogopts + formatteropts + |
1568 @command(b'perfrevlogchunks', revlogopts + formatteropts + |
1419 [('e', 'engines', '', 'compression engines to use'), |
1569 [(b'e', b'engines', b'', b'compression engines to use'), |
1420 ('s', 'startrev', 0, 'revision to start at')], |
1570 (b's', b'startrev', 0, b'revision to start at')], |
1421 '-c|-m|FILE') |
1571 b'-c|-m|FILE') |
1422 def perfrevlogchunks(ui, repo, file_=None, engines=None, startrev=0, **opts): |
1572 def perfrevlogchunks(ui, repo, file_=None, engines=None, startrev=0, **opts): |
1423 """Benchmark operations on revlog chunks. |
1573 """Benchmark operations on revlog chunks. |
1424 |
1574 |
1425 Logically, each revlog is a collection of fulltext revisions. However, |
1575 Logically, each revlog is a collection of fulltext revisions. However, |
1426 stored within each revlog are "chunks" of possibly compressed data. This |
1576 stored within each revlog are "chunks" of possibly compressed data. This |
1742 for name in possiblefilters: |
1900 for name in possiblefilters: |
1743 subset = subsettable.get(name) |
1901 subset = subsettable.get(name) |
1744 if subset not in possiblefilters: |
1902 if subset not in possiblefilters: |
1745 break |
1903 break |
1746 else: |
1904 else: |
1747 assert False, 'subset cycle %s!' % possiblefilters |
1905 assert False, b'subset cycle %s!' % possiblefilters |
1748 allfilters.append(name) |
1906 allfilters.append(name) |
1749 possiblefilters.remove(name) |
1907 possiblefilters.remove(name) |
1750 |
1908 |
1751 # warm the cache |
1909 # warm the cache |
1752 if not full: |
1910 if not full: |
1753 for name in allfilters: |
1911 for name in allfilters: |
1754 repo.filtered(name).branchmap() |
1912 repo.filtered(name).branchmap() |
1755 if not filternames or 'unfiltered' in filternames: |
1913 if not filternames or b'unfiltered' in filternames: |
1756 # add unfiltered |
1914 # add unfiltered |
1757 allfilters.append(None) |
1915 allfilters.append(None) |
1758 |
1916 |
1759 branchcacheread = safeattrsetter(branchmap, 'read') |
1917 branchcacheread = safeattrsetter(branchmap, b'read') |
1760 branchcachewrite = safeattrsetter(branchmap.branchcache, 'write') |
1918 branchcachewrite = safeattrsetter(branchmap.branchcache, b'write') |
1761 branchcacheread.set(lambda repo: None) |
1919 branchcacheread.set(lambda repo: None) |
1762 branchcachewrite.set(lambda bc, repo: None) |
1920 branchcachewrite.set(lambda bc, repo: None) |
1763 try: |
1921 try: |
1764 for name in allfilters: |
1922 for name in allfilters: |
1765 printname = name |
1923 printname = name |
1766 if name is None: |
1924 if name is None: |
1767 printname = 'unfiltered' |
1925 printname = b'unfiltered' |
1768 timer(getbranchmap(name), title=str(printname)) |
1926 timer(getbranchmap(name), title=str(printname)) |
1769 finally: |
1927 finally: |
1770 branchcacheread.restore() |
1928 branchcacheread.restore() |
1771 branchcachewrite.restore() |
1929 branchcachewrite.restore() |
1772 fm.end() |
1930 fm.end() |
1773 |
1931 |
1774 @command('perfloadmarkers') |
1932 @command(b'perfbranchmapload', [ |
|
1933 (b'f', b'filter', b'', b'Specify repoview filter'), |
|
1934 (b'', b'list', False, b'List brachmap filter caches'), |
|
1935 ] + formatteropts) |
|
1936 def perfbranchmapread(ui, repo, filter=b'', list=False, **opts): |
|
1937 """benchmark reading the branchmap""" |
|
1938 opts = _byteskwargs(opts) |
|
1939 |
|
1940 if list: |
|
1941 for name, kind, st in repo.cachevfs.readdir(stat=True): |
|
1942 if name.startswith(b'branch2'): |
|
1943 filtername = name.partition(b'-')[2] or b'unfiltered' |
|
1944 ui.status(b'%s - %s\n' |
|
1945 % (filtername, util.bytecount(st.st_size))) |
|
1946 return |
|
1947 if filter: |
|
1948 repo = repoview.repoview(repo, filter) |
|
1949 else: |
|
1950 repo = repo.unfiltered() |
|
1951 # try once without timer, the filter may not be cached |
|
1952 if branchmap.read(repo) is None: |
|
1953 raise error.Abort(b'No brachmap cached for %s repo' |
|
1954 % (filter or b'unfiltered')) |
|
1955 timer, fm = gettimer(ui, opts) |
|
1956 timer(lambda: branchmap.read(repo) and None) |
|
1957 fm.end() |
|
1958 |
|
1959 @command(b'perfloadmarkers') |
1775 def perfloadmarkers(ui, repo): |
1960 def perfloadmarkers(ui, repo): |
1776 """benchmark the time to parse the on-disk markers for a repo |
1961 """benchmark the time to parse the on-disk markers for a repo |
1777 |
1962 |
1778 Result is the number of markers in the repo.""" |
1963 Result is the number of markers in the repo.""" |
1779 timer, fm = gettimer(ui) |
1964 timer, fm = gettimer(ui) |
1780 svfs = getsvfs(repo) |
1965 svfs = getsvfs(repo) |
1781 timer(lambda: len(obsolete.obsstore(svfs))) |
1966 timer(lambda: len(obsolete.obsstore(svfs))) |
1782 fm.end() |
1967 fm.end() |
1783 |
1968 |
1784 @command('perflrucachedict', formatteropts + |
1969 @command(b'perflrucachedict', formatteropts + |
1785 [('', 'size', 4, 'size of cache'), |
1970 [(b'', b'costlimit', 0, b'maximum total cost of items in cache'), |
1786 ('', 'gets', 10000, 'number of key lookups'), |
1971 (b'', b'mincost', 0, b'smallest cost of items in cache'), |
1787 ('', 'sets', 10000, 'number of key sets'), |
1972 (b'', b'maxcost', 100, b'maximum cost of items in cache'), |
1788 ('', 'mixed', 10000, 'number of mixed mode operations'), |
1973 (b'', b'size', 4, b'size of cache'), |
1789 ('', 'mixedgetfreq', 50, 'frequency of get vs set ops in mixed mode')], |
1974 (b'', b'gets', 10000, b'number of key lookups'), |
|
1975 (b'', b'sets', 10000, b'number of key sets'), |
|
1976 (b'', b'mixed', 10000, b'number of mixed mode operations'), |
|
1977 (b'', b'mixedgetfreq', 50, b'frequency of get vs set ops in mixed mode')], |
1790 norepo=True) |
1978 norepo=True) |
1791 def perflrucache(ui, size=4, gets=10000, sets=10000, mixed=10000, |
1979 def perflrucache(ui, mincost=0, maxcost=100, costlimit=0, size=4, |
1792 mixedgetfreq=50, **opts): |
1980 gets=10000, sets=10000, mixed=10000, mixedgetfreq=50, **opts): |
|
1981 opts = _byteskwargs(opts) |
|
1982 |
1793 def doinit(): |
1983 def doinit(): |
1794 for i in xrange(10000): |
1984 for i in _xrange(10000): |
1795 util.lrucachedict(size) |
1985 util.lrucachedict(size) |
1796 |
1986 |
|
1987 costrange = list(range(mincost, maxcost + 1)) |
|
1988 |
1797 values = [] |
1989 values = [] |
1798 for i in xrange(size): |
1990 for i in _xrange(size): |
1799 values.append(random.randint(0, sys.maxint)) |
1991 values.append(random.randint(0, _maxint)) |
1800 |
1992 |
1801 # Get mode fills the cache and tests raw lookup performance with no |
1993 # Get mode fills the cache and tests raw lookup performance with no |
1802 # eviction. |
1994 # eviction. |
1803 getseq = [] |
1995 getseq = [] |
1804 for i in xrange(gets): |
1996 for i in _xrange(gets): |
1805 getseq.append(random.choice(values)) |
1997 getseq.append(random.choice(values)) |
1806 |
1998 |
1807 def dogets(): |
1999 def dogets(): |
1808 d = util.lrucachedict(size) |
2000 d = util.lrucachedict(size) |
1809 for v in values: |
2001 for v in values: |
1810 d[v] = v |
2002 d[v] = v |
1811 for key in getseq: |
2003 for key in getseq: |
1812 value = d[key] |
2004 value = d[key] |
1813 value # silence pyflakes warning |
2005 value # silence pyflakes warning |
1814 |
2006 |
|
2007 def dogetscost(): |
|
2008 d = util.lrucachedict(size, maxcost=costlimit) |
|
2009 for i, v in enumerate(values): |
|
2010 d.insert(v, v, cost=costs[i]) |
|
2011 for key in getseq: |
|
2012 try: |
|
2013 value = d[key] |
|
2014 value # silence pyflakes warning |
|
2015 except KeyError: |
|
2016 pass |
|
2017 |
1815 # Set mode tests insertion speed with cache eviction. |
2018 # Set mode tests insertion speed with cache eviction. |
1816 setseq = [] |
2019 setseq = [] |
1817 for i in xrange(sets): |
2020 costs = [] |
1818 setseq.append(random.randint(0, sys.maxint)) |
2021 for i in _xrange(sets): |
|
2022 setseq.append(random.randint(0, _maxint)) |
|
2023 costs.append(random.choice(costrange)) |
|
2024 |
|
2025 def doinserts(): |
|
2026 d = util.lrucachedict(size) |
|
2027 for v in setseq: |
|
2028 d.insert(v, v) |
|
2029 |
|
2030 def doinsertscost(): |
|
2031 d = util.lrucachedict(size, maxcost=costlimit) |
|
2032 for i, v in enumerate(setseq): |
|
2033 d.insert(v, v, cost=costs[i]) |
1819 |
2034 |
1820 def dosets(): |
2035 def dosets(): |
1821 d = util.lrucachedict(size) |
2036 d = util.lrucachedict(size) |
1822 for v in setseq: |
2037 for v in setseq: |
1823 d[v] = v |
2038 d[v] = v |
1824 |
2039 |
1825 # Mixed mode randomly performs gets and sets with eviction. |
2040 # Mixed mode randomly performs gets and sets with eviction. |
1826 mixedops = [] |
2041 mixedops = [] |
1827 for i in xrange(mixed): |
2042 for i in _xrange(mixed): |
1828 r = random.randint(0, 100) |
2043 r = random.randint(0, 100) |
1829 if r < mixedgetfreq: |
2044 if r < mixedgetfreq: |
1830 op = 0 |
2045 op = 0 |
1831 else: |
2046 else: |
1832 op = 1 |
2047 op = 1 |
1833 |
2048 |
1834 mixedops.append((op, random.randint(0, size * 2))) |
2049 mixedops.append((op, |
|
2050 random.randint(0, size * 2), |
|
2051 random.choice(costrange))) |
1835 |
2052 |
1836 def domixed(): |
2053 def domixed(): |
1837 d = util.lrucachedict(size) |
2054 d = util.lrucachedict(size) |
1838 |
2055 |
1839 for op, v in mixedops: |
2056 for op, v, cost in mixedops: |
1840 if op == 0: |
2057 if op == 0: |
1841 try: |
2058 try: |
1842 d[v] |
2059 d[v] |
1843 except KeyError: |
2060 except KeyError: |
1844 pass |
2061 pass |
1845 else: |
2062 else: |
1846 d[v] = v |
2063 d[v] = v |
1847 |
2064 |
|
2065 def domixedcost(): |
|
2066 d = util.lrucachedict(size, maxcost=costlimit) |
|
2067 |
|
2068 for op, v, cost in mixedops: |
|
2069 if op == 0: |
|
2070 try: |
|
2071 d[v] |
|
2072 except KeyError: |
|
2073 pass |
|
2074 else: |
|
2075 d.insert(v, v, cost=cost) |
|
2076 |
1848 benches = [ |
2077 benches = [ |
1849 (doinit, 'init'), |
2078 (doinit, b'init'), |
1850 (dogets, 'gets'), |
|
1851 (dosets, 'sets'), |
|
1852 (domixed, 'mixed') |
|
1853 ] |
2079 ] |
|
2080 |
|
2081 if costlimit: |
|
2082 benches.extend([ |
|
2083 (dogetscost, b'gets w/ cost limit'), |
|
2084 (doinsertscost, b'inserts w/ cost limit'), |
|
2085 (domixedcost, b'mixed w/ cost limit'), |
|
2086 ]) |
|
2087 else: |
|
2088 benches.extend([ |
|
2089 (dogets, b'gets'), |
|
2090 (doinserts, b'inserts'), |
|
2091 (dosets, b'sets'), |
|
2092 (domixed, b'mixed') |
|
2093 ]) |
1854 |
2094 |
1855 for fn, title in benches: |
2095 for fn, title in benches: |
1856 timer, fm = gettimer(ui, opts) |
2096 timer, fm = gettimer(ui, opts) |
1857 timer(fn, title=title) |
2097 timer(fn, title=title) |
1858 fm.end() |
2098 fm.end() |
1859 |
2099 |
1860 @command('perfwrite', formatteropts) |
2100 @command(b'perfwrite', formatteropts) |
1861 def perfwrite(ui, repo, **opts): |
2101 def perfwrite(ui, repo, **opts): |
1862 """microbenchmark ui.write |
2102 """microbenchmark ui.write |
1863 """ |
2103 """ |
|
2104 opts = _byteskwargs(opts) |
|
2105 |
1864 timer, fm = gettimer(ui, opts) |
2106 timer, fm = gettimer(ui, opts) |
1865 def write(): |
2107 def write(): |
1866 for i in range(100000): |
2108 for i in range(100000): |
1867 ui.write(('Testing write performance\n')) |
2109 ui.write((b'Testing write performance\n')) |
1868 timer(write) |
2110 timer(write) |
1869 fm.end() |
2111 fm.end() |
1870 |
2112 |
1871 def uisetup(ui): |
2113 def uisetup(ui): |
1872 if (util.safehasattr(cmdutil, 'openrevlog') and |
2114 if (util.safehasattr(cmdutil, b'openrevlog') and |
1873 not util.safehasattr(commands, 'debugrevlogopts')): |
2115 not util.safehasattr(commands, b'debugrevlogopts')): |
1874 # for "historical portability": |
2116 # for "historical portability": |
1875 # In this case, Mercurial should be 1.9 (or a79fea6b3e77) - |
2117 # In this case, Mercurial should be 1.9 (or a79fea6b3e77) - |
1876 # 3.7 (or 5606f7d0d063). Therefore, '--dir' option for |
2118 # 3.7 (or 5606f7d0d063). Therefore, '--dir' option for |
1877 # openrevlog() should cause failure, because it has been |
2119 # openrevlog() should cause failure, because it has been |
1878 # available since 3.5 (or 49c583ca48c4). |
2120 # available since 3.5 (or 49c583ca48c4). |
1879 def openrevlog(orig, repo, cmd, file_, opts): |
2121 def openrevlog(orig, repo, cmd, file_, opts): |
1880 if opts.get('dir') and not util.safehasattr(repo, 'dirlog'): |
2122 if opts.get(b'dir') and not util.safehasattr(repo, b'dirlog'): |
1881 raise error.Abort("This version doesn't support --dir option", |
2123 raise error.Abort(b"This version doesn't support --dir option", |
1882 hint="use 3.5 or later") |
2124 hint=b"use 3.5 or later") |
1883 return orig(repo, cmd, file_, opts) |
2125 return orig(repo, cmd, file_, opts) |
1884 extensions.wrapfunction(cmdutil, 'openrevlog', openrevlog) |
2126 extensions.wrapfunction(cmdutil, b'openrevlog', openrevlog) |