D805: alias: make alias command lazily resolved
quark (Jun Wu)
phabricator at mercurial-scm.org
Sat Sep 23 20:57:54 UTC 2017
quark created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
With many aliases, resolving them could have some visible overhead. Below is
part of traceprof [1] output of `hg bookmark --hidden`:
(time unit: ms)
37 \ addaliases dispatch.py:526
37 | __init__ (60 times) dispatch.py:402
33 | findcmd (108 times) cmdutil.py:721
16 | findpossible (49 times) cmdutil.py:683
It may get better by optimizing `findcmd` to do a bisect, but we don't
really need to resolve an alias if it's not used, so let's make those
command entries lazy.
After this patch, `addalias` takes less than 1ms.
[1]: https://bitbucket.org/facebook/hg-experimental/src/9aca0dbdbdfc48457e5d2581ca2d6e662fced2e6/hgext3rd/traceprof.pyx
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D805
AFFECTED FILES
mercurial/dispatch.py
CHANGE DETAILS
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -523,6 +523,37 @@
ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
raise
+class lazyaliasentry(object):
+ """like a typical command entry (func, opts, help), but is lazy"""
+
+ def __init__(self, name, definition, cmdtable, source):
+ self.name = name
+ self.definition = definition
+ self.cmdtable = cmdtable.copy()
+ self.source = source
+
+ @util.propertycache
+ def _aliasdef(self):
+ return cmdalias(self.name, self.definition, self.cmdtable, self.source)
+
+ def __getitem__(self, n):
+ aliasdef = self._aliasdef
+ if n == 0:
+ return aliasdef
+ elif n == 1:
+ return aliasdef.opts
+ elif n == 2:
+ return aliasdef.help
+ else:
+ raise IndexError
+
+ def __iter__(self):
+ for i in range(3):
+ yield self[i]
+
+ def __len__(self):
+ return 3
+
def addaliases(ui, cmdtable):
# aliases are processed after extensions have been loaded, so they
# may use extension commands. Aliases can also use other alias definitions,
@@ -537,8 +568,8 @@
pass
source = ui.configsource('alias', alias)
- aliasdef = cmdalias(alias, definition, cmdtable, source)
- cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
+ entry = lazyaliasentry(alias, definition, cmdtable, source)
+ cmdtable[alias] = entry
def _parse(ui, args):
options = {}
To: quark, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list