contrib: remove revlog related perf tests

Summary:
Those tests are going to break with the latest changelog. We're moving away
from revlog so let's just remove the tests.

Reviewed By: DurhamG

Differential Revision: D22657198

fbshipit-source-id: 6d1540050d70c58636577fa3325daca511273a2b
This commit is contained in:
Jun Wu 2020-07-30 20:24:12 -07:00 committed by Facebook GitHub Bot
parent fad9d569cb
commit 3acb04ea22
2 changed files with 0 additions and 499 deletions

View File

@ -674,43 +674,6 @@ def perfbundleread(ui, repo, bundlepath, **opts):
fm.end()
@command(
"perfchangegroupchangelog",
formatteropts
+ [
("", "version", "02", "changegroup version"),
("r", "rev", "", "revisions to add to changegroup"),
],
)
def perfchangegroupchangelog(ui, repo, version="02", rev=None, **opts):
"""Benchmark producing a changelog group for a changegroup.
This measures the time spent processing the changelog during a
bundle operation. This occurs during `hg bundle` and on a server
processing a `getbundle` wire protocol request (handles clones
and pull requests).
By default, all revisions are added to the changegroup.
"""
cl = repo.changelog
revs = [cl.lookup(r) for r in repo.revs(rev or "all()")]
bundler = changegroup.getbundler(version, repo)
def lookup(node):
# The real bundler reads the revision in order to access the
# manifest node and files list. Do that here.
cl.read(node)
return node
def d():
for chunk in bundler.group(revs, cl, lookup):
pass
timer, fm = gettimer(ui, opts)
timer(d)
fm.end()
@command("perfdirs", formatteropts)
def perfdirs(ui, repo, **opts):
timer, fm = gettimer(ui, opts)
@ -1073,71 +1036,6 @@ def perffncacheencode(ui, repo, **opts):
fm.end()
@command(
"perfbdiff",
revlogopts
+ formatteropts
+ [
("", "count", 1, "number of revisions to test (when using --startrev)"),
("", "alldata", False, "test bdiffs for all associated revisions"),
],
"-c|-m|FILE REV",
)
def perfbdiff(ui, repo, file_, rev=None, count=None, **opts):
"""benchmark a bdiff between revisions
By default, benchmark a bdiff between its delta parent and itself.
With ``--count``, benchmark bdiffs between delta parents and self for N
revisions starting at the specified revision.
With ``--alldata``, assume the requested revision is a changeset and
measure bdiffs for all changes related to that changeset (manifest
and filelogs).
"""
if opts["alldata"]:
opts["changelog"] = True
if opts.get("changelog") or opts.get("manifest"):
file_, rev = None, file_
elif rev is None:
raise error.CommandError("perfbdiff", "invalid arguments")
textpairs = []
r = cmdutil.openrevlog(repo, "perfbdiff", file_, opts)
startrev = r.rev(r.lookup(rev))
for rev in range(startrev, min(startrev + count, len(r) - 1)):
if opts["alldata"]:
# Load revisions associated with changeset.
ctx = repo[rev]
mtext = repo.manifestlog._revlog.revision(ctx.manifestnode())
for pctx in ctx.parents():
pman = repo.manifestlog._revlog.revision(pctx.manifestnode())
textpairs.append((pman, mtext))
# Load filelog revisions by iterating manifest delta.
man = ctx.manifest()
pman = ctx.p1().manifest()
for filename, change in pman.diff(man).items():
fctx = repo.file(filename)
f1 = fctx.revision(change[0][0] or -1)
f2 = fctx.revision(change[1][0] or -1)
textpairs.append((f1, f2))
else:
dp = r.deltaparent(rev)
textpairs.append((r.revision(dp), r.revision(rev)))
def d():
for pair in textpairs:
mdiff.textdiff(*pair)
timer, fm = gettimer(ui, opts)
timer(d)
fm.end()
@command("perfdiffwd", formatteropts)
def perfdiffwd(ui, repo, **opts):
"""Profile diff of working directory changes"""
@ -1161,396 +1059,6 @@ def perfdiffwd(ui, repo, **opts):
fm.end()
@command("perfrevlogindex", revlogopts + formatteropts, "-c|-m|FILE")
def perfrevlogindex(ui, repo, file_=None, **opts):
"""Benchmark operations against a revlog index.
This tests constructing a revlog instance, reading index data,
parsing index data, and performing various operations related to
index data.
"""
rl = cmdutil.openrevlog(repo, "perfrevlogindex", file_, opts)
opener = getattr(rl, "opener") # trick linter
indexfile = rl.indexfile
data = opener.read(indexfile)
header = struct.unpack(">I", data[0:4])[0]
version = header & 0xFFFF
if version == 1:
revlogio = revlog.revlogio()
inline = header & (1 << 16)
else:
raise error.Abort(("unsupported revlog version: %d") % version)
rllen = len(rl)
node0 = rl.node(0)
node25 = rl.node(rllen // 4)
node50 = rl.node(rllen // 2)
node75 = rl.node(rllen // 4 * 3)
node100 = rl.node(rllen - 1)
allrevs = range(rllen)
allrevsrev = list(reversed(allrevs))
allnodes = [rl.node(rev) for rev in range(rllen)]
allnodesrev = list(reversed(allnodes))
def constructor():
revlog.revlog(opener, indexfile)
def read():
with opener(indexfile) as fh:
fh.read()
def parseindex():
revlogio.parseindex(data, inline)
def getentry(revornode):
index = revlogio.parseindex(data, inline)[0]
index[revornode]
def getentries(revs, count=1):
index = revlogio.parseindex(data, inline)[0]
for i in range(count):
for rev in revs:
index[rev]
def resolvenode(node):
nodemap = revlogio.parseindex(data, inline)[1]
# This only works for the C code.
if nodemap is None:
return
try:
nodemap[node]
except error.RevlogError:
pass
def resolvenodes(nodes, count=1):
nodemap = revlogio.parseindex(data, inline)[1]
if nodemap is None:
return
for i in range(count):
for node in nodes:
try:
nodemap[node]
except error.RevlogError:
pass
benches = [
(constructor, "revlog constructor"),
(read, "read"),
(parseindex, "create index object"),
(lambda: getentry(0), "retrieve index entry for rev 0"),
(lambda: resolvenode("a" * 20), "look up missing node"),
(lambda: resolvenode(node0), "look up node at rev 0"),
(lambda: resolvenode(node25), "look up node at 1/4 len"),
(lambda: resolvenode(node50), "look up node at 1/2 len"),
(lambda: resolvenode(node75), "look up node at 3/4 len"),
(lambda: resolvenode(node100), "look up node at tip"),
# 2x variation is to measure caching impact.
(lambda: resolvenodes(allnodes), "look up all nodes (forward)"),
(lambda: resolvenodes(allnodes, 2), "look up all nodes 2x (forward)"),
(lambda: resolvenodes(allnodesrev), "look up all nodes (reverse)"),
(lambda: resolvenodes(allnodesrev, 2), "look up all nodes 2x (reverse)"),
(lambda: getentries(allrevs), "retrieve all index entries (forward)"),
(lambda: getentries(allrevs, 2), "retrieve all index entries 2x (forward)"),
(lambda: getentries(allrevsrev), "retrieve all index entries (reverse)"),
(lambda: getentries(allrevsrev, 2), "retrieve all index entries 2x (reverse)"),
]
for fn, title in benches:
timer, fm = gettimer(ui, opts)
timer(fn, title=title)
fm.end()
@command(
"perfrevlogrevisions",
revlogopts
+ formatteropts
+ [
("d", "dist", 100, "distance between the revisions"),
("s", "startrev", 0, "revision to start reading at"),
("", "reverse", False, "read in reverse"),
],
"-c|-m|FILE",
)
def perfrevlogrevisions(ui, repo, file_=None, startrev=0, reverse=False, **opts):
"""Benchmark reading a series of revisions from a revlog.
By default, we read every ``-d/--dist`` revision from 0 to tip of
the specified revlog.
The start revision can be defined via ``-s/--startrev``.
"""
rl = cmdutil.openrevlog(repo, "perfrevlogrevisions", file_, opts)
rllen = getlen(ui)(rl)
def d():
rl.clearcaches()
beginrev = startrev
endrev = rllen
dist = opts["dist"]
if reverse:
beginrev, endrev = endrev, beginrev
dist = -1 * dist
for x in xrange(beginrev, endrev, dist):
# Old revisions don't support passing int.
n = rl.node(x)
rl.revision(n)
timer, fm = gettimer(ui, opts)
timer(d)
fm.end()
@command(
"perfrevlogchunks",
revlogopts
+ formatteropts
+ [
("e", "engines", "", "compression engines to use"),
("s", "startrev", 0, "revision to start at"),
],
"-c|-m|FILE",
)
def perfrevlogchunks(ui, repo, file_=None, engines=None, startrev=0, **opts):
"""Benchmark operations on revlog chunks.
Logically, each revlog is a collection of fulltext revisions. However,
stored within each revlog are "chunks" of possibly compressed data. This
data needs to be read and decompressed or compressed and written.
This command measures the time it takes to read+decompress and recompress
chunks in a revlog. It effectively isolates I/O and compression performance.
For measurements of higher-level operations like resolving revisions,
see ``perfrevlogrevisions`` and ``perfrevlogrevision``.
"""
rl = cmdutil.openrevlog(repo, "perfrevlogchunks", file_, opts)
# _chunkraw was renamed to _getsegmentforrevs.
try:
segmentforrevs = rl._getsegmentforrevs
except AttributeError:
segmentforrevs = rl._chunkraw
# Verify engines argument.
if engines:
engines = set(e.strip() for e in engines.split(","))
for engine in engines:
try:
util.compressionengines[engine]
except KeyError:
raise error.Abort("unknown compression engine: %s" % engine)
else:
engines = []
for e in util.compengines:
engine = util.compengines[e]
try:
if engine.available():
engine.revlogcompressor().compress("dummy")
engines.append(e)
except NotImplementedError:
pass
revs = list(rl.revs(startrev, len(rl) - 1))
def rlfh(rl):
if rl._inline:
return getsvfs(repo)(rl.indexfile)
else:
return getsvfs(repo)(rl.datafile)
def doread():
rl.clearcaches()
for rev in revs:
segmentforrevs(rev, rev)
def doreadcachedfh():
rl.clearcaches()
fh = rlfh(rl)
for rev in revs:
segmentforrevs(rev, rev, df=fh)
def doreadbatch():
rl.clearcaches()
segmentforrevs(revs[0], revs[-1])
def doreadbatchcachedfh():
rl.clearcaches()
fh = rlfh(rl)
segmentforrevs(revs[0], revs[-1], df=fh)
def dochunk():
rl.clearcaches()
fh = rlfh(rl)
for rev in revs:
rl._chunk(rev, df=fh)
chunks = [None]
def dochunkbatch():
rl.clearcaches()
fh = rlfh(rl)
# Save chunks as a side-effect.
chunks[0] = rl._chunks(revs, df=fh)
def docompress(compressor):
rl.clearcaches()
try:
# Swap in the requested compression engine.
oldcompressor = rl._compressor
rl._compressor = compressor
for chunk in chunks[0]:
rl.compress(chunk)
finally:
rl._compressor = oldcompressor
benches = [
(lambda: doread(), "read"),
(lambda: doreadcachedfh(), "read w/ reused fd"),
(lambda: doreadbatch(), "read batch"),
(lambda: doreadbatchcachedfh(), "read batch w/ reused fd"),
(lambda: dochunk(), "chunk"),
(lambda: dochunkbatch(), "chunk batch"),
]
for engine in sorted(engines):
compressor = util.compengines[engine].revlogcompressor()
benches.append(
(functools.partial(docompress, compressor), "compress w/ %s" % engine)
)
for fn, title in benches:
timer, fm = gettimer(ui, opts)
timer(fn, title=title)
fm.end()
@command(
"perfrevlogrevision",
revlogopts
+ formatteropts
+ [("", "cache", False, "use caches instead of clearing")],
"-c|-m|FILE REV",
)
def perfrevlogrevision(ui, repo, file_, rev=None, cache=None, **opts):
"""Benchmark obtaining a revlog revision.
Obtaining a revlog revision consists of roughly the following steps:
1. Compute the delta chain
2. Obtain the raw chunks for that delta chain
3. Decompress each raw chunk
4. Apply binary patches to obtain fulltext
5. Verify hash of fulltext
This command measures the time spent in each of these phases.
"""
if opts.get("changelog") or opts.get("manifest"):
file_, rev = None, file_
elif rev is None:
raise error.CommandError("perfrevlogrevision", "invalid arguments")
r = cmdutil.openrevlog(repo, "perfrevlogrevision", file_, opts)
# _chunkraw was renamed to _getsegmentforrevs.
try:
segmentforrevs = r._getsegmentforrevs
except AttributeError:
segmentforrevs = r._chunkraw
node = r.lookup(rev)
rev = r.rev(node)
def getrawchunks(data, chain):
start = r.start
length = r.length
inline = r._inline
iosize = r._io.size
buffer = util.buffer
offset = start(chain[0])
chunks = []
ladd = chunks.append
for rev in chain:
chunkstart = start(rev)
if inline:
chunkstart += (rev + 1) * iosize
chunklength = length(rev)
ladd(buffer(data, chunkstart - offset, chunklength))
return chunks
def dodeltachain(rev):
if not cache:
r.clearcaches()
r._deltachain(rev)
def doread(chain):
if not cache:
r.clearcaches()
segmentforrevs(chain[0], chain[-1])
def dorawchunks(data, chain):
if not cache:
r.clearcaches()
getrawchunks(data, chain)
def dodecompress(chunks):
decomp = r.decompress
for chunk in chunks:
decomp(chunk)
def dopatch(text, bins):
if not cache:
r.clearcaches()
mdiff.patches(text, bins)
def dohash(text):
if not cache:
r.clearcaches()
r.checkhash(text, node, rev=rev)
def dorevision():
if not cache:
r.clearcaches()
r.revision(node)
chain = r._deltachain(rev)[0]
data = segmentforrevs(chain[0], chain[-1])[1]
rawchunks = getrawchunks(data, chain)
bins = r._chunks(chain)
text = str(bins[0])
bins = bins[1:]
text = mdiff.patches(text, bins)
benches = [
(lambda: dorevision(), "full"),
(lambda: dodeltachain(rev), "deltachain"),
(lambda: doread(chain), "read"),
(lambda: dorawchunks(data, chain), "rawchunks"),
(lambda: dodecompress(rawchunks), "decompress"),
(lambda: dopatch(text, bins), "patch"),
(lambda: dohash(text), "hash"),
]
for fn, title in benches:
timer, fm = gettimer(ui, opts)
timer(fn, title=title)
fm.end()
@command(
"perfrevset",
[

View File

@ -45,11 +45,8 @@ perfstatus
$ hg perfancestors
$ hg perfancestorset 2
$ hg perfannotate a
$ hg perfbdiff -c 1
$ hg perfbdiff --alldata 1
$ hg perfbookmarks
$ hg perfcca
$ hg perfchangegroupchangelog
$ hg perfchangeset 2
$ hg perfctxfiles 2
$ hg perfdiffwd
@ -72,10 +69,6 @@ perfstatus
$ hg perfnodelookup 2
$ hg perfpathcopies 1 2
$ hg perfrawfiles 2
$ hg perfrevlogindex -c
$ hg perfrevlogrevisions .hg/store/data/a.i
$ hg perfrevlogrevision -m 0
$ hg perfrevlogchunks -c
$ hg perfrevrange
$ hg perfrevset 'all()'
$ hg perfstartup