changeset 16445:453c8670566c

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).
author Angel Ezquerra <angel.ezquerra@gmail.com>
date Fri, 13 Apr 2012 13:46:49 +0200
parents 432f198600c6
children 984e0412e82b
files mercurial/revset.py
diffstat 1 files changed, 9 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revset.py	Fri Apr 13 13:35:45 2012 +0200
+++ b/mercurial/revset.py	Fri Apr 13 13:46:49 2012 +0200
@@ -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