# HG changeset patch # User Angel Ezquerra # Date 1334317609 -7200 # Node ID 453c8670566c29c348d423facbdcd7af62ce9d07 # Parent 432f198600c6a4f9af1016c4c4045a1617063ff8 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 -r 432f198600c6 -r 453c8670566c mercurial/revset.py --- 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