[PATCH 2 of 4 V2] revset: speedup matching() by stopping the match early if a field does not match
Angel Ezquerra
angel.ezquerra at gmail.com
Sat Apr 14 22:33:56 UTC 2012
# HG changeset patch
# User Angel Ezquerra <angel.ezquerra at gmail.com>
# Date 1334317609 -7200
# Node ID effd8cdec977cddc33654cfc1a60bfbdd8d77af4
# Parent 972f44d002c5c18b966fd30be659a9d7424cd89a
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
@@ -970,19 +970,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