[PATCH 2 of 2] perf: benchmark command for revlog indexes
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Sat May 27 07:34:42 EDT 2017
On 05/27/2017 05:41 AM, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc at gmail.com>
> # Date 1495856487 25200
> # Fri May 26 20:41:27 2017 -0700
> # Node ID 84ec213e509859c3d983ba537b25a025d61f31d9
> # Parent 684fbf0453f4abc3c2ccabc05cef3f4233d6476c
> perf: benchmark command for revlog indexes
Looks good and works good, Thanks! I've marked it as pre-reviewed.
I've added a small python 3 nits below.
> We didn't have explicit microbenchmark coverage for loading revlog
> indexes. That seems like a useful thing to have, so let's add it.
>
> We currently measure the low-level nodemap APIs. There is room to
> hook in at the actual revlog layer. This could be done as a follow-up.
>
> The hackiest thing about this patch is specifying revlog paths.
> Other commands have arguments that allow resolution of changelog,
> manifest, and filelog. I needed to hook in at a lower level of
> the revlog API than what the existing helper functions to resolve
> revlogs allowed. I was too lazy to write some new APIs. This could
> be done as a follow-up easily enough.
>
> Example output for `hg perfrevlogindex 00changelog.i` on my
> Firefox repo (404418 revisions):
>
> ! revlog constructor
> ! wall 0.003106 comb 0.000000 user 0.000000 sys 0.000000 (best of 912)
> ! read
> ! wall 0.003077 comb 0.000000 user 0.000000 sys 0.000000 (best of 924)
> ! create index object
> ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 1803994)
> ! retrieve index entry for rev 0
> ! wall 0.000193 comb 0.000000 user 0.000000 sys 0.000000 (best of 14037)
> ! look up missing node
> ! wall 0.003313 comb 0.000000 user 0.000000 sys 0.000000 (best of 865)
> ! look up node at rev 0
> ! wall 0.003295 comb 0.010000 user 0.010000 sys 0.000000 (best of 858)
> ! look up node at 1/4 len
> ! wall 0.002598 comb 0.010000 user 0.010000 sys 0.000000 (best of 1103)
> ! look up node at 1/2 len
> ! wall 0.001909 comb 0.000000 user 0.000000 sys 0.000000 (best of 1507)
> ! look up node at 3/4 len
> ! wall 0.001213 comb 0.000000 user 0.000000 sys 0.000000 (best of 2275)
> ! look up node at tip
> ! wall 0.000453 comb 0.000000 user 0.000000 sys 0.000000 (best of 5697)
> ! look up all nodes (forward)
> ! wall 0.094615 comb 0.100000 user 0.100000 sys 0.000000 (best of 100)
> ! look up all nodes (reverse)
> ! wall 0.045889 comb 0.050000 user 0.050000 sys 0.000000 (best of 100)
> ! retrieve all index entries (forward)
> ! wall 0.078398 comb 0.080000 user 0.060000 sys 0.020000 (best of 100)
> ! retrieve all index entries (reverse)
> ! wall 0.079376 comb 0.080000 user 0.070000 sys 0.010000 (best of 100)
>
> diff --git a/contrib/perf.py b/contrib/perf.py
> --- a/contrib/perf.py
> +++ b/contrib/perf.py
> @@ -23,6 +23,7 @@ import functools
> import gc
> import os
> import random
> +import struct
> import sys
> import time
> from mercurial import (
> @@ -34,6 +35,7 @@ from mercurial import (
> extensions,
> mdiff,
> merge,
> + revlog,
> util,
> )
>
> @@ -61,6 +63,10 @@ try:
> from mercurial import scmutil # since 1.9 (or 8b252e826c68)
> except ImportError:
> pass
> +try:
> + from mercurial import pycompat # since 3.8 (or 6041fb8f2da8)
> +except ImportError:
> + pass
>
> # for "historical portability":
> # define util.safehasattr forcibly, because util.safehasattr has been
> @@ -857,6 +863,106 @@ def perfdiffwd(ui, repo, **opts):
> timer(d, title)
> fm.end()
>
> + at command('perfrevlogindex', formatteropts, 'FILE')
> +def perfrevlogindex(ui, repo, file_, **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.
> + """
> +
> + opener = getsvfs(repo)
> +
> + data = opener.read(file_)
> +
> + 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)
> +
> + rl = revlog.revlog(opener, file_)
> + rllen = len(rl)
> +
> + node0 = rl.node(0)
> + node25 = rl.node(rllen / 4)
> + node50 = rl.node(rllen / 2)
> + node75 = rl.node(rllen / 4 * 3)
note, you want these to be "//" instead of "/" or python 3 will get you.
Cheers,
--
Pierre-Yves David
More information about the Mercurial-devel
mailing list