Gregory Szorc <gregory.szorc@gmail.com> [Mon, 07 Nov 2016 18:39:08 -0800] rev 30365
util: remove decompressors dict (API)
All in-tree consumers are now using the compengines registrar.
Extensions should switch to it as well.
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 07 Nov 2016 18:38:13 -0800] rev 30364
changegroup: use compression engines API
The new API doesn't have the equivalence for None and 'UN' so we
introduce code to use 'UN' explicitly.
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 07 Nov 2016 18:36:48 -0800] rev 30363
bundle2: use compression engines API to obtain decompressor
Like the recent change for the compressor side, this too is
relatively straightforward. We now store a compression engine
on the instance instead of a low-level decompressor. Again, this
will allow us to easily transition to different compression engine
APIs when they are implemented.
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 07 Nov 2016 18:34:51 -0800] rev 30362
util: remove compressors dict (API)
We no longer have any in-tree consumers of this object. Use
util.compengines instead.
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 07 Nov 2016 18:35:43 -0800] rev 30361
bundle2: use new compression engine API for compression
Now that we have a new API to define compression engines, let's put it
to use!
The new code stores a reference to the compression engine instead of
a low-level compressor object. This will allow us to more easily
transition to different APIs on the compression engine interface
once we implement them.
As part of this, we change the registration in bundletypes to use 'UN'
instead of None. Previously, util.compressors had the no-op compressor
registered under both the 'UN' and None keys. Since we're switching to
a new API, I don't see the point in carrying this dual registration
forward.
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 07 Nov 2016 18:31:39 -0800] rev 30360
util: create new abstraction for compression engines
Currently, util.py has "compressors" and "decompressors" dicts
mapping compression algorithms to callables returning objects that
perform well-defined operations. In addition, revlog.py has code
for calling into a compressor or decompressor explicitly. And, there
is code in the wire protocol for performing zlib compression.
The 3rd party lz4revlog extension has demonstrated the utility of
supporting alternative compression formats for revlog storage. But
it stops short of supporting lz4 for bundles and the wire protocol.
There are also plans to support zstd as a general compression
replacement.
So, there appears to be a market for a unified API for registering
compression engines. This commit starts the process of establishing
one.
This commit establishes a base class/interface for defining
compression engines and how they will be used. A collection class
to hold references to registered compression engines has also been
introduced.
The built-in zlib, bz2, truncated bz2, and no-op compression engines
are registered with a singleton instance of the collection class.
The compression engine API will change once consumers are ported
to the new API and some common patterns can be simplified at the
engine API level. So don't get too attached to the API...
Augie Fackler <augie@google.com> [Sun, 09 Oct 2016 09:25:39 -0400] rev 30359
config: mark parser regexes as bytes explicitly
r-strings are not transformed into bytes by our source transformer magic.
Augie Fackler <augie@google.com> [Sun, 09 Oct 2016 09:17:49 -0400] rev 30358
ui: explicitly open config files in binary mode
This has been working mostly accidentally, but now it works explicitly.
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 09 Nov 2016 16:04:44 -0800] rev 30357
help: fix double word usage
"most" was used twice.
(I fixed a grammar error before timeless spotted it!)
Jun Wu <quark@fb.com> [Wed, 09 Nov 2016 22:08:30 +0000] rev 30356
setup: move cffi stuff to mercurial/cffi
This patch moves all setup*cffi stuff to mercurial/cffi to make the root
directory cleaner. The idea was from mpm [1]:
> It seems like we could have a fair amount of cffi definitions, and
> cluttering the root directory (or mercurial/) with them is probably not
> a great long-term solution. We could probably add a cffi/ directory
> under mercurial/ to parallel pure/.
[1]: https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-July/086442.html
Durham Goode <durham@fb.com> [Tue, 08 Nov 2016 08:03:43 -0800] rev 30355
manifest: remove manifest.add and add memmfctx.write
This removes one more dependency on the manifest class by moving the write
functionality onto the memmanifestctx classes and changing the one consumer to
use the new API.
By moving the write path to a manifestctx, we now give the individual manifests
control over how they're read and serialized. This will be useful in developing
new manifest formats and storage systems.
Durham Goode <durham@fb.com> [Tue, 08 Nov 2016 08:03:43 -0800] rev 30354
context: add manifestctx property on changectx
This allows us to access the manifestctx for a given commit. This will be used
in a later patch to be able to copy the manifestctx when we want to make a new
commit.
Durham Goode <durham@fb.com> [Tue, 08 Nov 2016 08:03:43 -0800] rev 30353
manifest: add copy to mfctx classes
This adds copy functionality to the manifestctx classes. This will be used in an
upcoming diff to copy a manifestctx during commit so we can modify the manifest
before committing.
Durham Goode <durham@fb.com> [Tue, 08 Nov 2016 08:03:43 -0800] rev 30352
manifest: introduce memmanifestctx and memtreemanifestctx
This introduces two new classes to represent in-memory manifest instances.
Similar to memchangectx, this lets us prepare a manifest in memory, then in a
future patch we will add the apis that can commit this in memory structure.
Durham Goode <durham@fb.com> [Tue, 08 Nov 2016 08:03:43 -0800] rev 30351
manifestctx: add _revlog() function
The `self._repo.manifestlog._revlog` code is getting copy and pasted a lot in
manifestctx. Let's make it a function so it can be reused. This will make future
patches cleaner too.
Durham Goode <durham@fb.com> [Tue, 08 Nov 2016 08:03:43 -0800] rev 30350
manifest: remove manifest.find
As part of removing dependencies on manifest, this drops the find function and
fixes up the two existing callers to use the equivalent apis on manifestctx.
Durham Goode <durham@fb.com> [Tue, 08 Nov 2016 08:03:43 -0800] rev 30349
changegroup: remove remaining uses of repo.manifest
The remaining uses of repo.manifest in the changegroup module are treating the
manifest exclusively as a revlog, so let's replace them with instances of the
revlog directly.
This is part of dropping all dependencies on repo.manifest in favor of
repo.manifestlog.
Martin von Zweigbergk <martinvonz@google.com> [Fri, 04 Nov 2016 13:49:15 -0700] rev 30348
treemanifest: fix a "treeinmem" case
f2c5b9d48b29 (manifest: make treemanifestctx store the repo,
2016-10-18) broke most tests when run with treeinmem=True. The
treeinmem mode can not be enabled by the user, so this did not break
anything in practice, but it's useful to have it working for testing
the treemanifest code.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 06 Nov 2016 10:46:55 -0800] rev 30347
perf: support measuring bdiff for all changeset related data
The --all argument changes the behavior of `perfbdiff` to pull
in fulltext revision pairs for all changes related to a changeset.
The p1 and p2 manifests will be bdiffed against current. Every file
that changed between p1 and current will have its file revisions
loaded and bdiffed.
This mode of operation effectively measured the bdiff time required
for `hg commit`.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 06 Nov 2016 11:01:25 -0800] rev 30346
perf: support bdiffing multiple revisions in a single revlog
This is useful for testing bdiff performance on several revision
pairs at a time.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 06 Nov 2016 09:51:14 -0800] rev 30345
perf: prepare to handle multiple pairs in perfbdiff
Before, we only supported benchmarking a single pair of texts
with bdiff. We want to enable feeding larger corpora into this
benchmark. So rewrite the code to support that.
Yuya Nishihara <yuya@tcha.org> [Wed, 09 Nov 2016 22:06:09 +0900] rev 30344
py3: document why os.fsencode() can be used to get back bytes argv
And a possible Windows issue. I'm sad we have to do such ugly hack, but
that's the unicode on Python 3.
Yuya Nishihara <yuya@tcha.org> [Wed, 09 Nov 2016 22:15:51 +0900] rev 30343
py3: update test-check-py3-compat.t output
4b1af1c867fa (scmutil: move util.termwidth()) changed where the import fails.
Mads Kiilerich <madski@unity3d.com> [Mon, 17 Oct 2016 23:16:55 +0200] rev 30342
spelling: fixes of non-dictionary words
Durham Goode <durham@fb.com> [Thu, 03 Nov 2016 17:31:14 -0700] rev 30341
manifest: add __nonzero__ method
This adds a __nonzero__ method to manifestdict. This isn't strictly necessary in
the vanilla Mercurial implementation, since Python will handle nonzero checks by
using __len__, but having it implemented here makes it easier for alternative
implementations to implement __nonzero__ and have them be plug-n-play with the
normal implementation.
Pulkit Goyal <7895pulkit@gmail.com> [Sun, 06 Nov 2016 04:36:26 +0530] rev 30340
py3: have bytes version of sys.argv
sys.argv returns unicodes on Python 3. We need a bytes version for us.
There was also a python bug/feature request which wanted then to implement
one. They rejected and it is quoted in one of the comments that we can use
fsencode() to get a bytes version of sys.argv. Though not sure about its
correctness.
Link to the comment: http://bugs.python.org/issue8776#msg217416
After this patch we will have pycompat.sysargv which will return us bytes
version of sys.argv. If this patch goes in, i will like to make transformer
rewrite sys.argv with pycompat.argv because there are lot of occurences.
Augie Fackler <augie@google.com> [Sun, 09 Oct 2016 09:00:47 -0400] rev 30339
util: use '\\' rather than using r'\'
We need bytes, and I find this just a little more immediately obvious
than doing rb'\'.
Augie Fackler <augie@google.com> [Sun, 09 Oct 2016 09:03:10 -0400] rev 30338
util: use pycompat urlunquote function
Augie Fackler <augie@google.com> [Sun, 09 Oct 2016 09:02:25 -0400] rev 30337
pycompat: introduce an alias for urllib.unquote
We have to use unquote_to_bytes on Python 3, so we need an abstraction
for this.
Christian Ebert <blacktrash@gmx.net> [Mon, 17 Oct 2016 17:42:46 +0200] rev 30336
keyword: handle filectx _customcmp
Suggested by Yuya Nishihara:
https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089461.html
Related to issue5364.
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 22:20:31 +0900] rev 30335
mail: do not print(), use ui.debug() instead
Since print() can't take a bytes output, it's pretty useless in Mercurial
on Python 3. As this is a debug message, switching to ui.debug() seems fine.
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 22:12:48 +0900] rev 30334
progress: obtain stderr from ui
This will help Python 3 porting.
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 22:09:50 +0900] rev 30333
simplemerge: obtain stdout from ui
This will help Python 3 porting.
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 22:07:03 +0900] rev 30332
profiling: obtain stderr from ui
This will help Python 3 porting.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 06 Nov 2016 18:51:57 -0800] rev 30331
bdiff: replace hash algorithm
This patch replaces lyhash with the hash algorithm used by diffutils.
The algorithm has its origins in Git commit 2e9d1410, which is all the
way back from 1992. The license header in the code at that revision
in GPL v2.
I have not performed an extensive analysis of the distribution
(and therefore buckets) of hash output. However, `hg perfbdiff`
gives some clear wins. I'd like to think that if it is good enough
for diffutils it is good enough for us?
From the mozilla-unified repository:
$ perfbdiff -m 3041e4d59df2
! wall 0.053271 comb 0.060000 user 0.060000 sys 0.000000 (best of 100)
! wall 0.035827 comb 0.040000 user 0.040000 sys 0.000000 (best of 100)
$ perfbdiff 0e9928989e9c --alldata --count 100
! wall 6.204277 comb 6.200000 user 6.200000 sys 0.000000 (best of 3)
! wall 4.309710 comb 4.300000 user 4.300000 sys 0.000000 (best of 3)
From the hg repo:
$ perfbdiff 35000 --alldata --count 1000
! wall 0.660358 comb 0.660000 user 0.660000 sys 0.000000 (best of 15)
! wall 0.534092 comb 0.530000 user 0.530000 sys 0.000000 (best of 19)
Looking at the generated assembly and statistical profiler output
from the kernel level, I believe there is room to make this function
even faster. Namely, we're still consuming data character by character
instead of at the word level. This translates to more loop iterations
and more instructions.
At this juncture though, the real performance killer is that we're
hashing every line. We should get a significant speedup if we change
the algorithm to find the longest prefix, longest suffix, treat those
as single "lines" and then only do the line splitting and hashing on
the parts that are different. That will require a lot of C code,
however. I'm optimistic this approach could result in a ~2x speedup.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 04 Nov 2016 21:44:25 -0700] rev 30330
profiling: make statprof the default profiler (BC)
The statprof sampling profiler runs with significantly less overhead.
Its data is therefore more useful. Furthermore, its default output
shows the hotpath by default, which I've found to be way more useful
than the default profiler's function time table.
There is one behavioral regression with this change worth noting:
the statprof profiler currently doesn't profile individual hgweb
requests like lsprof does. This is because the current implementation
of statprof only profiles the thread that started profiling.
The ability for lsprof to profile individual hgweb requests is
relatively new and likely not widely used. Furthermore, I have plans
to modify statprof to support profiling multiple threads. I expect
that change to go through several iterations. I'm submitting this
patch first so there is more time to test statprof. Perfect is the
enemy of good.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 04 Nov 2016 20:50:38 -0700] rev 30329
profiling: use vendored statprof and upstream enhancements (BC)
Now that the statprof module is vendored and suitable for use, we
switch our statprof profiler to use it. This required some minor
changes because of drift between the official statprof profiler
and the vendored copy.
We also incorporate Facebook's improvements from the "statprofext"
extension at
https://bitbucket.org/facebook/hg-experimental, notably support for
different display formats.
Because statprof output is different, this is marked as BC. Although
most users likely won't notice since most users don't profile.
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 23:16:32 +0900] rev 30328
crecord: use scmutil.termsize()
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 23:09:05 +0900] rev 30327
scmutil: extend termwidth() to return terminal height, renamed to termsize()
It appears crecord.py has its own termsize() function. I want to get rid of it.
The fallback height is chosen from the default of cmd.exe on Windows, and
VT100 on Unix.
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 22:57:12 +0900] rev 30326
scmutil: clarify that we explicitly do termwidth - 1 on Windows
I was a bit confused since we didn't add 1 to the width, which is different
from the example shown in StackOverflow.
http://stackoverflow.com/a/12642749
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 21:57:32 +0900] rev 30325
scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 21:50:29 +0900] rev 30324
scmutil: narrow ImportError handling in termwidth()
The array module must exist. It's sufficient to suppress the ImportError of
termios. Also salvaged the comment why we have to handle AttributeError, from
7002bb17cc5e.
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 21:42:11 +0900] rev 30323
scmutil: make termwidth() obtain stdio from ui
I'm getting rid of direct sys.stderr|out|in references so Py3 porting will
be slightly easier.
Yuya Nishihara <yuya@tcha.org> [Thu, 20 Oct 2016 21:38:44 +0900] rev 30322
scmutil: move util.termwidth()
I'm going to get rid of sys.stderr|out|in references from posix.termwidth().
In order to do that, termwidth() needs to take a ui, but functions in util.py
shouldn't depend on a ui object. So moves termwidth() to scmutil.py.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 06 Nov 2016 00:37:50 -0700] rev 30321
bdiff: don't check border condition in loop
`plast = a + len - 1`. So, this "for" loop iterates from "a" to "plast",
inclusive. So, `p == plast` can only be true on the final iteration
of the loop. So checking for it on every loop iteration is wasteful.
This patch simply decreases the upper bound of the loop by 1 and
adds an explicit check after iteration for the `p == plast` case.
We can't simply add 1 to the initial value for "i" because that
doesn't do the correct thing on empty input strings.
`perfbdiff -m 3041e4d59df2` on the Firefox repo becomes significantly
faster:
! wall 0.072763 comb 0.070000 user 0.070000 sys 0.000000 (best of 100)
! wall 0.053221 comb 0.060000 user 0.060000 sys 0.000000 (best of 100)
For the curious, this code has its origins in 8b067bde6679, which is
the changeset that introduced bdiff.c in 2005.
Also, GNU diffutils is able to perform a similar line-based diff in
under 20ms. So there's likely more perf wins to be found in this code.
One of them is the hashing algorithm. But it looks like mpm spent
some time testing hash collisions in d0c48891dd4a. I'd like to do the
same before switching away from lyhash, just to be on the safe side.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 05 Nov 2016 23:41:52 -0700] rev 30320
perf: add perfbdiff
bdiff shows up a lot in profiling. I think it would be useful to have
a perf command that runs bdiff over and over so we can find hot spots.
Pulkit Goyal <7895pulkit@gmail.com> [Sun, 06 Nov 2016 06:54:31 +0530] rev 30319
help: show help for disabled extensions (issue5228)
This patch does not exactly solve issue5228 but it results in a better
condition on this issue. For disabled extensions, we used to parse the
module and get the first occurrences of docstring and then return the first
line of that as an introductory heading of extension. This is what we get
today.
This patch returns the whole docstring of the module as a help for extension,
which is more informative. There are some modules which don't have much
docstring at top level except the heading so those are unaffected by this
change. To follow the existing trend of showing commands either we have to
load the extension or have a very ugly parsing method which don't even assure
correctness.
Pulkit Goyal <7895pulkit@gmail.com> [Sun, 06 Nov 2016 04:17:19 +0530] rev 30318
py3: make scmutil.rcpath() return bytes
This patch make sure scmutil.rcpath() returns bytes independent of
which platform is used on Python 3. If we want to change type for windows we
can just conditionalize the return variable.
Pulkit Goyal <7895pulkit@gmail.com> [Sun, 06 Nov 2016 04:10:33 +0530] rev 30317
py3: use pycompat.ossep at certain places
Certain instances of os.sep has been converted to pycompat.ossep where it was
sure to use bytes only. There are more such instances which needs some more
attention and will get surely.
Pulkit Goyal <7895pulkit@gmail.com> [Sun, 06 Nov 2016 03:44:44 +0530] rev 30316
py3: have pycompat.ospathsep and pycompat.ossep
We needed bytes version of os.sep and os.pathsep in py3 as they return
unicodes.
Pulkit Goyal <7895pulkit@gmail.com> [Sun, 06 Nov 2016 03:33:22 +0530] rev 30315
py3: add a bytes version of os.name
os.name returns unicodes on py3. Most of our checks are like
os.name == 'nt'
Because of the transformer, on the right hand side we have b'nt'. The
condition will never satisfy even if os.name returns 'nt' as that will be an
unicode.
We either need to encode every occurence of os.name or have a
new variable which is much cleaner. Now we have pycompat.osname.
There are around 53 occurences of os.name in the codebase which needs to
be replaced by pycompat.osname to support Python 3.
Pulkit Goyal <7895pulkit@gmail.com> [Sun, 06 Nov 2016 12:18:23 +0900] rev 30314
py3: make util.datapath a bytes variable
In this patch we make util.datapath a bytes variable, but we have to pass a
unicode to gettext.translation otherwise it will cry. Used pycompat.fsdecode()
to decode it back to unicode as it was converted to bytes using
pycompat.fsencode().
Pulkit Goyal <7895pulkit@gmail.com> [Sun, 06 Nov 2016 03:12:40 +0530] rev 30313
py3: add os.fsdecode() as pycompat.fsdecode()
We need to use os.fsdecode() but this was not present in Python 2. So added
the function in pycompat.py
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 04 Nov 2016 20:22:37 -0700] rev 30312
statprof: return state from stop()
I don't like global variables. Have stop() return the captured
state so callers can pass data to the display function.
Yuya Nishihara <yuya@tcha.org> [Sat, 05 Nov 2016 13:20:53 +0900] rev 30311
hghave: check darcs version more strictly
test-convert-darcs.t suddenly started failing on my Debian sid machine. The
reason was Darcs was upgraded from 2.12.0 to 2.12.4 so the original pattern
got to match the last two digits. Fix the pattern to match 2.2+.
Yuya Nishihara <yuya@tcha.org> [Sat, 05 Nov 2016 13:16:40 +0900] rev 30310
tests: silence output of darcs command
It appears darcs is more verbose by default these days. I got test failure
with Darcs 2.12.4.
Durham Goode <durham@fb.com> [Wed, 02 Nov 2016 17:10:47 -0700] rev 30309
manifest: remove manifest.readshallowdelta
This removes manifest.readshallowdelta and converts its one consumer to use
manifestlog instead.
Durham Goode <durham@fb.com> [Wed, 02 Nov 2016 17:10:47 -0700] rev 30308
manifest: get rid of manifest.readshallowfast
This removes manifest.readshallowfast and converts it's one user to use
manifestlog instead.
Durham Goode <durham@fb.com> [Wed, 02 Nov 2016 17:10:47 -0700] rev 30307
manifest: add shallow option to treemanifestctx.readdelta and readfast
The old manifest had different functions for performing shallow reads, shallow
readdeltas, and shallow readfasts. Since a lot of the code is duplicate (and
since those functions don't make sense on a normal manifestctx), let's unify
them into flags on the existing readdelta and readfast functions.
A future diff will change consumers of these functions to use the manifestctx
versions and will delete the old apis.
Durham Goode <durham@fb.com> [Wed, 02 Nov 2016 17:10:47 -0700] rev 30306
manifest: change manifestlog mancache to be directory based
In the last patch we added a get() function that allows fetching directory level
treemanifestctxs. It didn't handle caching at directory level though, so we need to
change our mancache to support multiple directories.
Durham Goode <durham@fb.com> [Wed, 02 Nov 2016 17:24:06 -0700] rev 30305
manifest: add manifestlog.get to obtain subdirectory instances
Previously manifestlog only allowed obtaining root level manifests. Future
patches will need direct access to subdirectory manifests as part of changegroup
creation, so let's add a get() function that knows how to deal with
subdirectories.
Durham Goode <durham@fb.com> [Wed, 02 Nov 2016 17:33:31 -0700] rev 30304
manifest: throw LookupError if node not in revlog
When accessing a manifest via manifestlog[node], let's verify that the node
actually exists and throw a LookupError if it doesn't. This matches the old read
behavior, so we don't accidentally return invalid manifestctxs.
We do this in manifestlog instead of in the manifestctx/treemanifestctx
constructors because the treemanifest code currently relies on the fact that
certain code paths can produce treemanifests without touching the revlogs (and
it has tests that verify things work if certain revlogs are missing entirely, so
they break if we add validation that tries to read them).
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 23 Oct 2016 10:40:33 -0700] rev 30303
revlog: optimize _chunkraw when startrev==endrev
In many cases, _chunkraw() is called with startrev==endrev. When
this is true, we can avoid an extra index lookup and some other
minor operations.
On the mozilla-unified repo, `hg perfrevlogchunks -c` says this
has the following impact:
! read w/ reused fd
! wall 0.371846 comb 0.370000 user 0.350000 sys 0.020000 (best of 27)
! wall 0.337930 comb 0.330000 user 0.300000 sys 0.030000 (best of 30)
! read batch w/ reused fd
! wall 0.014952 comb 0.020000 user 0.000000 sys 0.020000 (best of 197)
! wall 0.014866 comb 0.010000 user 0.000000 sys 0.010000 (best of 196)
So, we've gone from ~25x slower than batch to ~22.5x slower.
At this point, there's probably not much else we can do except
implement an optimized function in the index itself, including in C.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 22 Oct 2016 15:41:23 -0700] rev 30302
revlog: inline start() and end() for perf reasons
When I implemented `hg perfrevlogchunks`, one of the things that
stood out was N * _chunk() calls was ~38x slower than 1
_chunks() call. Specifically, on the mozilla-unified repo:
N*_chunk: 0.528997s
1*_chunks: 0.013735s
This repo has 352,097 changesets. So the average time per changeset
comes out to:
N*_chunk: 1.502us
1*_chunks: 0.039us
If you extrapolate these numbers to a repository with 1M changesets,
that comes out to 1.502s versus 0.039s, which is significant.
At these latencies, Python attribute lookups and function calls
matter. So, this patch inlines some code to cut down on that overhead.
The impact of this patch on N*_chunk() calls is clear:
! wall 0.528997 comb 0.520000 user 0.500000 sys 0.020000 (best of 19)
! wall 0.367723 comb 0.370000 user 0.350000 sys 0.020000 (best of 27)
So, we go from ~38x slower to ~27x. A nice improvement. But there's
still a long way to go.
It's worth noting that functionality like revsets perform changelog
lookups one revision at a time. So this code path is worth optimizing.