From patchwork Fri Mar 29 16:16:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [4, of, 4] revset: replace "repo.changelog" to avoid iteration for each "x in subset" From: Katsunori FUJIWARA X-Patchwork-Id: 1218 Message-Id: <78452fc8ab54526c7a31.1364573794@feefifofum> To: mercurial-devel@selenic.com Date: Sat, 30 Mar 2013 01:16:34 +0900 # HG changeset patch # User FUJIWARA Katsunori # Date 1364573132 -32400 # Node ID 78452fc8ab54526c7a31189327185a954e197397 # Parent 8af24dd8f88c5f8011ae32bb7256977c94eab238 revset: replace "repo.changelog" to avoid iteration for each "x in subset" Before this patch, some revset predicates uses "repo.changelog" as "subset" for sub-expressions to mean "whole revisions in repository". But "changelog" doesn't have "__contains__()", and causes iteration for each "x in subset" in sub-expressions. This patch replaces "repo.changelog" by "_safesubset(repo)" to avoid such iteration. This patch affects predicates below: - rangeset(":") - ancestorspec("~") - parentspec("^") - matching - roots Performance improvement can be measured by combination with predicates examining "x in subset": "last", for example. Results of "hg perfrevset" for each revspec (before/after this patch) on the repository containing 40000 revisions are shown below: - "last(tip):last(tip)": ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 685) ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 13680) - "(last(tip))~1": ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 686) ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 1295) - "(last(tip))^1": ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 682) ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 1292) - "tip and matching(last(tip))": ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 1172) ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 6481) - "roots(last(tip))": ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 665) ! wall 0.000000 comb 0.000000 user 0.000000 sys 0.000000 (best of 1284) diff -r 8af24dd8f88c -r 78452fc8ab54 mercurial/revset.py --- a/mercurial/revset.py Sat Mar 30 01:05:32 2013 +0900 +++ b/mercurial/revset.py Sat Mar 30 01:05:32 2013 +0900 @@ -239,9 +239,9 @@ return stringset(repo, subset, x) def rangeset(repo, subset, x, y): - cl = repo.changelog - m = getset(repo, cl, x) - n = getset(repo, cl, y) + rl = _safesubset(repo) + m = getset(repo, rl, x) + n = getset(repo, rl, y) if not m or not n: return [] @@ -350,7 +350,7 @@ raise error.ParseError(_("~ expects a number")) ps = set() cl = repo.changelog - for r in getset(repo, cl, x): + for r in getset(repo, _safesubset(repo), x): for i in range(n): r = cl.parentrevs(r)[0] ps.add(r) @@ -1163,7 +1163,7 @@ raise error.ParseError(_("^ expects a number 0, 1, or 2")) ps = set() cl = repo.changelog - for r in getset(repo, cl, x): + for r in getset(repo, _safesubset(repo), x): if n == 0: ps.add(r) elif n == 1: @@ -1281,7 +1281,7 @@ # i18n: "matching" is a keyword l = getargs(x, 1, 2, _("matching takes 1 or 2 arguments")) - revs = getset(repo, repo.changelog, l[0]) + revs = getset(repo, _safesubset(repo), l[0]) fieldlist = ['metadata'] if len(l) > 1: @@ -1379,7 +1379,7 @@ """``roots(set)`` Changesets in set with no parent changeset in set. """ - s = set(getset(repo, repo.changelog, x)) + s = set(getset(repo, _safesubset(repo), x)) subset = [r for r in subset if r in s] cs = _children(repo, subset, s) return [r for r in subset if r not in cs]