Show More
@@ -2,12 +2,14 | |||||
2 | '''helper extension to measure performance''' |
|
2 | '''helper extension to measure performance''' | |
3 |
|
3 | |||
4 | from mercurial import cmdutil, scmutil, util, commands, obsolete |
|
4 | from mercurial import cmdutil, scmutil, util, commands, obsolete | |
5 | from mercurial import repoview, branchmap, merge, copies, error |
|
5 | from mercurial import repoview, branchmap, merge, copies, error, revlog | |
|
6 | from mercurial import mdiff | |||
6 | import time, os, sys |
|
7 | import time, os, sys | |
7 | import random |
|
8 | import random | |
8 | import functools |
|
9 | import functools | |
9 |
|
10 | |||
10 | formatteropts = commands.formatteropts |
|
11 | formatteropts = commands.formatteropts | |
|
12 | revlogopts = commands.debugrevlogopts | |||
11 |
|
13 | |||
12 | cmdtable = {} |
|
14 | cmdtable = {} | |
13 | command = cmdutil.command(cmdtable) |
|
15 | command = cmdutil.command(cmdtable) | |
@@ -488,6 +490,96 def perfrevlog(ui, repo, file_, **opts): | |||||
488 | timer(d) |
|
490 | timer(d) | |
489 | fm.end() |
|
491 | fm.end() | |
490 |
|
492 | |||
|
493 | @command('perfrevlogrevision', revlogopts + formatteropts + | |||
|
494 | [('', 'cache', False, 'use caches instead of clearing')], | |||
|
495 | '-c|-m|FILE REV') | |||
|
496 | def perfrevlogrevision(ui, repo, file_, rev=None, cache=None, **opts): | |||
|
497 | """Benchmark obtaining a revlog revision. | |||
|
498 | ||||
|
499 | Obtaining a revlog revision consists of roughly the following steps: | |||
|
500 | ||||
|
501 | 1. Compute the delta chain | |||
|
502 | 2. Obtain the raw chunks for that delta chain | |||
|
503 | 3. Decompress each raw chunk | |||
|
504 | 4. Apply binary patches to obtain fulltext | |||
|
505 | 5. Verify hash of fulltext | |||
|
506 | ||||
|
507 | This command measures the time spent in each of these phases. | |||
|
508 | """ | |||
|
509 | if opts.get('changelog') or opts.get('manifest'): | |||
|
510 | file_, rev = None, file_ | |||
|
511 | elif rev is None: | |||
|
512 | raise error.CommandError('perfrevlogrevision', 'invalid arguments') | |||
|
513 | ||||
|
514 | r = cmdutil.openrevlog(repo, 'perfrevlogrevision', file_, opts) | |||
|
515 | node = r.lookup(rev) | |||
|
516 | rev = r.rev(node) | |||
|
517 | ||||
|
518 | def dodeltachain(rev): | |||
|
519 | if not cache: | |||
|
520 | r.clearcaches() | |||
|
521 | r._deltachain(rev) | |||
|
522 | ||||
|
523 | def doread(chain): | |||
|
524 | if not cache: | |||
|
525 | r.clearcaches() | |||
|
526 | r._chunkraw(chain[0], chain[-1]) | |||
|
527 | ||||
|
528 | def dodecompress(data, chain): | |||
|
529 | if not cache: | |||
|
530 | r.clearcaches() | |||
|
531 | ||||
|
532 | start = r.start | |||
|
533 | length = r.length | |||
|
534 | inline = r._inline | |||
|
535 | iosize = r._io.size | |||
|
536 | buffer = util.buffer | |||
|
537 | offset = start(chain[0]) | |||
|
538 | ||||
|
539 | for rev in chain: | |||
|
540 | chunkstart = start(rev) | |||
|
541 | if inline: | |||
|
542 | chunkstart += (rev + 1) * iosize | |||
|
543 | chunklength = length(rev) | |||
|
544 | b = buffer(data, chunkstart - offset, chunklength) | |||
|
545 | revlog.decompress(b) | |||
|
546 | ||||
|
547 | def dopatch(text, bins): | |||
|
548 | if not cache: | |||
|
549 | r.clearcaches() | |||
|
550 | mdiff.patches(text, bins) | |||
|
551 | ||||
|
552 | def dohash(text): | |||
|
553 | if not cache: | |||
|
554 | r.clearcaches() | |||
|
555 | r._checkhash(text, node, rev) | |||
|
556 | ||||
|
557 | def dorevision(): | |||
|
558 | if not cache: | |||
|
559 | r.clearcaches() | |||
|
560 | r.revision(node) | |||
|
561 | ||||
|
562 | chain = r._deltachain(rev)[0] | |||
|
563 | data = r._chunkraw(chain[0], chain[-1]) | |||
|
564 | bins = r._chunks(chain) | |||
|
565 | text = str(bins[0]) | |||
|
566 | bins = bins[1:] | |||
|
567 | text = mdiff.patches(text, bins) | |||
|
568 | ||||
|
569 | benches = [ | |||
|
570 | (lambda: dorevision(), 'full'), | |||
|
571 | (lambda: dodeltachain(rev), 'deltachain'), | |||
|
572 | (lambda: doread(chain), 'read'), | |||
|
573 | (lambda: dodecompress(data, chain), 'decompress'), | |||
|
574 | (lambda: dopatch(text, bins), 'patch'), | |||
|
575 | (lambda: dohash(text), 'hash'), | |||
|
576 | ] | |||
|
577 | ||||
|
578 | for fn, title in benches: | |||
|
579 | timer, fm = gettimer(ui, opts) | |||
|
580 | timer(fn, title=title) | |||
|
581 | fm.end() | |||
|
582 | ||||
491 | @command('perfrevset', |
|
583 | @command('perfrevset', | |
492 | [('C', 'clear', False, 'clear volatile cache between each call.'), |
|
584 | [('C', 'clear', False, 'clear volatile cache between each call.'), | |
493 | ('', 'contexts', False, 'obtain changectx for each revision')] |
|
585 | ('', 'contexts', False, 'obtain changectx for each revision')] |
@@ -91,6 +91,8 perfstatus | |||||
91 | (no help text available) |
|
91 | (no help text available) | |
92 | perfrawfiles (no help text available) |
|
92 | perfrawfiles (no help text available) | |
93 | perfrevlog (no help text available) |
|
93 | perfrevlog (no help text available) | |
|
94 | perfrevlogrevision | |||
|
95 | Benchmark obtaining a revlog revision. | |||
94 | perfrevrange (no help text available) |
|
96 | perfrevrange (no help text available) | |
95 | perfrevset benchmark the execution time of a revset |
|
97 | perfrevset benchmark the execution time of a revset | |
96 | perfstartup (no help text available) |
|
98 | perfstartup (no help text available) | |
@@ -136,6 +138,7 perfstatus | |||||
136 | $ hg perfpathcopies 1 2 |
|
138 | $ hg perfpathcopies 1 2 | |
137 | $ hg perfrawfiles 2 |
|
139 | $ hg perfrawfiles 2 | |
138 | $ hg perfrevlog .hg/store/data/a.i |
|
140 | $ hg perfrevlog .hg/store/data/a.i | |
|
141 | $ hg perfrevlogrevision -m 0 | |||
139 | $ hg perfrevrange |
|
142 | $ hg perfrevrange | |
140 | $ hg perfrevset 'all()' |
|
143 | $ hg perfrevset 'all()' | |
141 | $ hg perfstartup |
|
144 | $ hg perfstartup |
General Comments 0
You need to be logged in to leave comments.
Login now