[PATCH 2 of 3] revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra
angel.ezquerra at gmail.com
Fri Apr 13 23:42:11 UTC 2012
# HG changeset patch
# User Angel Ezquerra <angel.ezquerra at gmail.com>
# Date 1334317609 -7200
# Node ID e735d3f86e7f96ebd78ea5080eb8f2db2220e63f
# Parent d10a02263e0c5197e3b7c5d3c10f713cfb3c7387
revset: speedup matching() by stopping the match early if a field does not match
Rather than getting all the fields that are being matches from every revision
and then comparing them to those of the target revision, compare each field one
by one and stop the match as soon as there is a match failure.
This can greatly reduce the match time when matching multiple fields.
The impact on match time when matching a single field seems negligible
(according to my measurements).
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -969,19 +969,22 @@
raise error.ParseError(
_("unexpected field name passed to matching: %s") % info)
getfieldfuncs.append(getfield)
-
# convert the getfield array of functions into a "getinfo" function
# which returns an array of field values (or a single value if there
# is only one field to match)
- if len(getfieldfuncs) == 1:
- getinfo = getfieldfuncs[0]
- else:
- getinfo = lambda r: [f(r) for f in getfieldfuncs]
+ getinfo = lambda r: [f(r) for f in getfieldfuncs]
matches = []
for rev in revs:
target = getinfo(rev)
- matches += [r for r in subset if getinfo(r) == target]
+ for r in subset:
+ match = True
+ for n, f in enumerate(getfieldfuncs):
+ if target[n] != f(r):
+ match = False
+ break
+ if match:
+ matches.append(r)
if len(revs) > 1:
matches = sorted(set(matches))
return matches
More information about the Mercurial-devel
mailing list